Annotation of mstools/samples/rpc/mandel/remote.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  REMOTE.C --
                      3:  *
                      4:  *  Code to do the remote calculations for the Windows Mandelbrot Set
                      5:  *  distributed drawing program.
                      6:  *
1.1.1.2 ! root        7:  *  Copyright (C) 1990, 1992 Microsoft Corporation.
1.1       root        8:  *
                      9:  *  Information coming into this module (via API calls) is based on
                     10:  *  upper-left being (0,0) (the Windows standard). We translate that
1.1.1.2 ! root       11:  *  to lower-left is (0,0) before we ship it out onto
1.1       root       12:  *  the net, and we do reverse translations accordingly.
                     13:  *
                     14:  *  The iteration data is passed back to the main window procedure
                     15:  *  (by means of a WM_PAINTLINE message) which draws the picture.
                     16:  *
                     17:  *  A word about the shared buffer: multiple buffers could be used, but
                     18:  *  a single one is used. The buffer is requested in this code, and
                     19:  *  then released after the data has been drawn (in PaintLine() in
                     20:  *  mandel.c). So long as the painting is done quickly, this is efficient.
                     21:  *
                     22:  *  This code sample is provided for demonstration purposes only.
                     23:  *  Microsoft makes no warranty, either express or implied,
                     24:  *  as to its usability in any given situation.
                     25:  */
                     26: 
                     27: 
                     28: #include <string.h>
                     29: #include <stdio.h>
                     30: #include <fcntl.h>
                     31: #include <sys\types.h>
                     32: #include <sys\stat.h>
                     33: #include <share.h>
                     34: #include <io.h>
                     35: #include <malloc.h>
                     36: 
                     37: #include <windows.h>
                     38: 
                     39: #ifdef RPC
                     40: #include <rpc.h>
                     41: #include "mdlrpc.h"
                     42: #endif
                     43: #include "mandel.h"
1.1.1.2 ! root       44: 
1.1       root       45: /*
1.1.1.2 ! root       46:  * Tuning parameters
1.1       root       47:  */
                     48: #define SVR_TABLE_SZ        20
                     49: #define MAX_PIPENAME_SZ     CCHMAXPATH
                     50: 
                     51: 
                     52: /*
                     53:  * Manifests, to keep everything neat.
                     54:  */
                     55: 
                     56: extern int errno;           // errno from c runtime
                     57: 
                     58: /*
                     59:  * Data structures
                     60:  */
                     61: extern svr_table    SvrTable[]; // the table
                     62: extern int          SvrTableSz;         // # of objects in it
                     63: char pszFail[255];
                     64: 
                     65: 
                     66: // Do we do local work?
                     67: BOOL    fLocalWork = TRUE;
                     68: BOOL    fRemoteWork = FALSE;
                     69: 
                     70: static int fDisplay = TRUE; /* display a message box for debug */
                     71: 
                     72: // Picture information
                     73: 
                     74:        int      cPictureID = 0;     // picture id, in case we reset in the middle
                     75: static CPOINT   cptLL;              // upper-left
                     76: static double   dPrecision;         // precision of draw
                     77: static LONGRECT    rclPicture;        // rectangle defining client window
                     78: static DWORD    dwCurrentLine;      // next line to be drawn
                     79: static DWORD    dwThreshold;        // threshold for iterations
                     80: 
                     81: 
                     82: static char szLocal[] = "Local machine";
                     83: #ifdef RPC
                     84: RPC_STATUS status;            // returned by RPC API function
                     85: #endif
                     86: /*
                     87:  * function prototypes for local procs
                     88:  */
                     89: 
                     90: DWORD CalcThreshold( double );
                     91: 
                     92: 
                     93: 
                     94: /*
                     95:  *  InitRemote --
                     96:  *
                     97:  *  This function initializes everything for our remote connections.
                     98:  *  It gets the local wksta name (making sure the wksta is started)
                     99:  *  and it creates the mailslot with which to collect replies to our poll.
                    100:  *
                    101:  *  RETURNS
                    102:  *
                    103:  *      TRUE        - initialization succeeded
                    104:  *      FALSE       - initialization failed, can't go on
                    105:  */
                    106: 
                    107: 
                    108: BOOL
                    109: InitRemote( HWND hWnd )
                    110: {
1.1.1.2 ! root      111: #ifdef RPC
        !           112:     RPC_STATUS status;            // returned by RPC API function
        !           113:     unsigned char * pszUuid = "12345678-1234-1234-1234-123456789ABC";
        !           114:     unsigned char * pszProtocolSequence = "ncacn_np";
        !           115:     unsigned char * pszNetworkAddress  = NULL;
        !           116:     unsigned char * pszEndpoint        = "\\pipe\\mandel";
        !           117:     unsigned char * pszOptions         = NULL;
        !           118:     unsigned char * pszStringBinding;  // long string
        !           119: #endif
        !           120: 
1.1       root      121: #ifndef RPC
                    122:     UNREFERENCED_PARAMETER(hWnd);
                    123: #endif
                    124: 
                    125:     // set up our local entry
                    126:     SvrTableSz++;
                    127:     strcpy(SvrTable[0].name, szLocal);
                    128:     SvrTable[0].iStatus = SS_LOCAL;
                    129: 
                    130: #ifdef RPC
1.1.1.2 ! root      131: /*  Select named pipes as the transport type and provide the   */
        !           132: /*  path to the server and named pipe that is used for RPC.     */
        !           133: 
        !           134: /*  Call the Microsoft RPC V1.0 Beta API function that lets      */
        !           135: /*  the client establish a connection with the server.           */
        !           136: 
        !           137:     status = RpcStringBindingCompose(pszUuid,
        !           138:                                      pszProtocolSequence,
        !           139:                                      pszNetworkAddress,
        !           140:                                      pszEndpoint,
        !           141:                                      pszOptions,
        !           142:                                     &pszStringBinding);
        !           143:     sprintf(pszFail, "RpcStringBindingCompose returned 0x%x for %s\n",
        !           144:            status, pszStringBinding);
        !           145:     MessageBox(hWnd, pszFail, "Mandelbrot RPC Application",
        !           146:                   MB_ICONINFORMATION | MB_SYSTEMMODAL);
1.1       root      147:     if (status) {
1.1.1.2 ! root      148:        PostMessage(hWnd, WM_DESTROY, 0, 0L);
        !           149:        return FALSE;
        !           150:     }
        !           151: 
        !           152:     status = RpcBindingFromStringBinding(pszStringBinding,
        !           153:                                         &hMandel);
        !           154: 
        !           155:     sprintf(pszFail, "RpcBindingFromStringBinding returned 0x%x for %s\n",\
        !           156:            status, pszStringBinding);
        !           157:     MessageBox(hWnd, pszFail, "Mandelbrot RPC Application",
        !           158:                   MB_ICONINFORMATION | MB_SYSTEMMODAL);
        !           159:     if (status) {
        !           160:        PostMessage(hWnd, WM_DESTROY, 0, 0L);
        !           161:        return FALSE;
1.1       root      162:     }
                    163: #endif
                    164: 
                    165:     // good, we succeeded
                    166:     return TRUE;
                    167: }
                    168: 
                    169: 
                    170: /*
                    171:  *  CheckDrawStatus --
                    172:  *
                    173:  *  This function does a check of all buffers being drawn.
                    174:  *
                    175:  *  If it finds an idle pipe, and there is work to be done, it assigns
                    176:  *      a line, and writes out the request.
                    177:  *  If it finds a read-pending pipe, it checks if the read has completed.
                    178:  *      If it has, it is read and a message is sent so the read data can
                    179:  *      be processed.
                    180:  *
                    181:  *  RETURNS
                    182:  *      TRUE        - we did a piece of work
                    183:  *      FALSE       - we could not find any work to do.
                    184:  */
                    185: 
                    186: BOOL CheckDrawStatus( HWND hwnd)
                    187: {
                    188: 
                    189:     static int  iWork = 0;
                    190:     int         iLast;
                    191:     CALCBUF     cb;
                    192:     PDWORD  pbBuf;
                    193: 
                    194:     // If no pipes, forget it
                    195:     if (SvrTableSz == 0)
                    196:         return FALSE;
                    197: 
                    198:     // Move on from where we left off
                    199: 
                    200:     iLast = iWork;
                    201: 
                    202:     while ( TRUE )
                    203:     {
                    204:       iWork++;
                    205: 
                    206:         if (iWork == SvrTableSz)
                    207:             iWork = 0;
                    208: 
                    209:         // Check the status
                    210:         switch(SvrTable[iWork].iStatus) {
                    211: 
                    212:         case SS_PAINTING:
                    213:             break;
                    214: 
                    215:         case SS_IDLE:
                    216:             // Idle; assign it a piece of work
                    217:             if ((long)dwCurrentLine > rclPicture.xRight)
                    218:                 break;
                    219: 
                    220:             if (!fRemoteWork)
                    221:                 break;
                    222:             // cb is of type CALCBUF;
                    223:             // rectangle, precision, threshold and complex point
                    224:             cb.rclDraw.xLeft = dwCurrentLine;
                    225:             cb.rclDraw.xRight = dwCurrentLine + iLines - 1;
                    226:             cb.rclDraw.yTop = rclPicture.yTop;
                    227:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    228:             cb.dblPrecision = dPrecision;
                    229:             cb.dwThreshold = dwThreshold;
                    230:             cb.cptLL = cptLL;
                    231: 
                    232:             SvrTable[iWork].dwLine = dwCurrentLine;
                    233:             dwCurrentLine += iLines;
                    234:             SvrTable[iWork].iStatus = SS_READPENDING;
                    235:             SvrTable[iWork].cPicture = cPictureID;
                    236:             SvrTable[iWork].cLines = iLines;
                    237: 
                    238:             return TRUE;
                    239: 
                    240:         case SS_LOCAL:
                    241:             // Do a chunk of work locally
                    242: 
                    243:             if ((long)dwCurrentLine > rclPicture.xRight) {
                    244:                 if (fContinueZoom == TRUE) {
                    245:                      if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC))
                    246:                         fZoomIn = FALSE;  // start zooming out
                    247:                      if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC))
                    248:                         fZoomIn = TRUE;
                    249:                      if (fZoomIn) {
                    250:                          CountHistogram();
                    251:                          rcZoom.top    = iHistMaxJ * (WIDTH/4);
                    252:                          rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1;
                    253:                          rcZoom.left   = iHistMaxI * (HEIGHT/4);
                    254:                          rcZoom.right  = rcZoom.left + (HEIGHT/4) - 1;
                    255:                          fRectDefined = TRUE;
                    256:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L);
                    257:                      }
                    258:                      else
                    259:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L);
                    260:                 }
                    261:                 break;
                    262:             }
                    263: 
                    264:             if (!TakeDrawBuffer())
                    265:                 break;
                    266: 
                    267:             pbBuf = GetDrawBuffer();
                    268: 
                    269:             cb.rclDraw.xLeft = dwCurrentLine;
                    270:             cb.rclDraw.xRight = dwCurrentLine+ iLines-1;
                    271:             cb.rclDraw.yTop = rclPicture.yTop;
                    272:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    273: 
                    274: 
                    275:             MandelCalc(&cptLL,
                    276:                        &(cb.rclDraw),
                    277:                        dPrecision,
                    278:                        dwThreshold,
                    279:                        (PLINEBUF)pbBuf);
                    280: 
                    281:             FreeDrawBuffer();
                    282: 
                    283:             SvrTable[iWork].cPicture = cPictureID;
                    284:             SvrTable[iWork].dwLine = dwCurrentLine;
                    285:             SvrTable[iWork].cLines = iLines;
                    286: 
                    287:             PostMessage(hwnd, WM_PAINTLINE,
                    288:                             (UINT)iWork,
                    289:                         0L);
                    290:             dwCurrentLine += iLines;
                    291:             return TRUE;
                    292: 
                    293:         }
                    294: 
                    295: 
                    296:         // If we made the full loop, we're done
                    297:         if (iWork == iLast)
                    298:             return FALSE;
                    299:     }
                    300: }
                    301: 
                    302: 
                    303: /*
                    304:  *  SetNewCalc --
                    305:  *
                    306:  *  This sets up new information for a drawing and
                    307:  *  updates the drawing ID so any calculations in progress will not
                    308:  *  be mixed in.
                    309:  */
                    310: 
                    311: void SetNewCalc( CPOINT cptUL, double dPrec, RECT rc)
                    312: {
                    313: 
                    314:     /*
                    315:      *  First, the base point. We need to translate from upper left to
                    316:      *  lower left.
                    317:      */
                    318: 
                    319:     cptLL.real = cptUL.real;
                    320:     cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top));
                    321: 
                    322:     // Now the precision
                    323:     dPrecision = dPrec;
                    324: 
                    325:     // The rectangle. Once again, translate.
                    326:     rclPicture.xLeft = (long) rc.left;
                    327:     rclPicture.xRight = (long) rc.right;
                    328:     rclPicture.yBottom = (long) rc.top;
                    329:     rclPicture.yTop = (long) rc.bottom;
                    330: 
                    331:     // Current line, start of drawing
                    332:     dwCurrentLine = rclPicture.xLeft;
                    333: 
                    334:     dwThreshold = CalcThreshold(dPrecision);
                    335: 
                    336: 
                    337: }
                    338: 
                    339: void IncPictureID(void)
                    340: {
                    341:     cPictureID++;
                    342: }
                    343: 
                    344: /*
                    345:  *  CheckDrawing --
                    346:  *
                    347:  *  Just a sanity check here -- a function to check to make sure that we're
                    348:  *  on the right drawing
                    349:  */
                    350: 
                    351: BOOL
                    352: CheckDrawingID( int id)
                    353: {
                    354:     return (id == cPictureID) ? TRUE : FALSE;
                    355: }
                    356: 
                    357: 
                    358: /*
                    359:  *  TakeDrawBuffer/ GetDrawBuffer/ FreeDrawBuffer / ReturnDrawBuffer
                    360:  *
                    361:  *  These functions hide a handle to a buffer of memory.
                    362:  *
                    363:  *  TakeDrawBuffer ensures only one pipe read at a time.
                    364:  *  GetDrawBuffer locks the handle and returns a pointer.
                    365:  *  FreeDrawBuffer unlocks the handle.
                    366:  *  ReturnDrawBuffer unlocks the handle and lets another pipe read go.
                    367:  */
                    368: 
                    369: static BOOL fBufferTaken = FALSE;
                    370: static HANDLE hSharedBuf = NULL;
                    371: 
                    372: 
                    373: BOOL
                    374: TakeDrawBuffer( void )
                    375: {
                    376: 
                    377:     if (fBufferTaken)
                    378:     {
                    379:         return FALSE;
                    380:     }
                    381: 
                    382:     if (hSharedBuf == NULL)
                    383:     {
1.1.1.2 ! root      384:        hSharedBuf = GlobalAlloc(GMEM_MOVEABLE, MAX_BUFSIZE);
1.1       root      385:         if (hSharedBuf == NULL)
                    386:             return FALSE;
                    387:     }
                    388:     fBufferTaken = TRUE;
                    389:     return TRUE;
                    390: }
                    391: 
                    392: 
                    393: 
                    394: PDWORD
                    395: GetDrawBuffer( void )
                    396: {
                    397: 
                    398:     if (hSharedBuf == NULL)
                    399:         return NULL;
                    400: 
1.1.1.2 ! root      401:     return (PDWORD) GlobalLock(hSharedBuf);
1.1       root      402: }
                    403: 
                    404: 
                    405: 
                    406: void
                    407: FreeDrawBuffer( void )
                    408: {
1.1.1.2 ! root      409:     GlobalUnlock(hSharedBuf);
1.1       root      410: }
                    411: 
                    412: 
                    413: void
                    414: ReturnDrawBuffer( void )
                    415: {
                    416:     fBufferTaken = FALSE;
                    417: }
                    418: 
                    419: 
                    420: 
                    421: /*
                    422:  *  CalcThreshold --
                    423:  *
                    424:  *  We need an iteration threshold beyond which we give up. We want it to
                    425:  *  increase the farther we zoom in. This code generates a threshold value
                    426:  *  based on the precision of drawing.
                    427:  *
                    428:  *  RETURNS
                    429:  *
                    430:  *      threshold calculated based on precision
                    431:  */
                    432: 
                    433: 
                    434: DWORD   CalcThreshold(double precision)
                    435: {
                    436:     DWORD   thres = 25;
1.1.1.2 ! root      437:     double  multiplier = (double) 100.0;
1.1       root      438: 
                    439:     /* for every 100, multiply by 2 */
1.1.1.2 ! root      440:     while ( (precision *= multiplier) < (double)1.0)
1.1       root      441:         thres *= 2;
                    442: 
                    443:     return thres;
                    444: }
                    445: 
                    446: 
                    447: 
                    448: /*
                    449:  *  QueryThreshold --
                    450:  *
                    451:  *  Callback for finding out what the current drawing's threshold is.
                    452:  */
                    453: 
                    454: DWORD QueryThreshold( void )
                    455: {
                    456:     return dwThreshold;
                    457: }
                    458: 
                    459: 
                    460: /*
                    461:  *
                    462:  *  GetServerCount --
                    463:  *
                    464:  *  Returns the number of servers in the table.
                    465:  */
                    466: 
                    467: int
                    468: GetServerCount( void )
                    469: {
                    470:     return (int) SvrTableSz-1;
                    471: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.