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

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:  *
                      7:  *  Copyright (C) 1990 Microsoft Corporation.
                      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
                     11:  *  to PM standard (lower-left is (0,0) ) before we ship it out onto
                     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: 
                     44: #include "mandel.h"
                     45: /*
                     46:  * Tuning paramters
                     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: {
                    111: #ifndef RPC
                    112:     UNREFERENCED_PARAMETER(hWnd);
                    113: #endif
                    114: 
                    115:     // set up our local entry
                    116:     SvrTableSz++;
                    117:     strcpy(SvrTable[0].name, szLocal);
                    118:     SvrTable[0].iStatus = SS_LOCAL;
                    119: 
                    120:     // set up remote entries
                    121: #ifdef RPC
                    122:     mdlrpc_ProtocolStack.TransportType = RPC_TRANSPORT_NAMEPIPE;
                    123:     mdlrpc_ProtocolStack.TransportInfo = "\\device\\namedpipe\\mdlrpc";
                    124:     mdlrpc_ProtocolStack.TransportInfoLength = \
                    125:     strlen(mdlrpc_ProtocolStack.TransportInfo) + 1;
                    126:                            // add 1 for terminating null
                    127: 
                    128:     /*  Call the Microsoft RPC V1.0 Alpha API function that lets     */
                    129:     /*  the client establish a connection with the server.           */
                    130:     /*  NOTE:  This API function will be replaced in future          */
                    131:     /*  releases by the standard DCE RPC function.                   */
                    132:     status = RpcBindToInterface(&mdlrpc_ProtocolStack,
                    133:                                 0L,
                    134:                                 &hMandel);
                    135:     if (status) {
                    136:         sprintf(pszFail, "RpcBindToInterface returned 0x%x\n", status);
                    137:         strcat(pszFail, "Please verify that the server side of the Mandel distributed application is running.\n");
                    138:         MessageBox(hWnd, pszFail, "Mandelbrot RPC Server Not Started",
                    139:                    MB_ICONHAND | MB_SYSTEMMODAL);
                    140:         PostMessage(hWnd, WM_DESTROY, 0, 0L);
                    141:         return FALSE;
                    142:     }
                    143: #endif
                    144: 
                    145:     // good, we succeeded
                    146:     return TRUE;
                    147: }
                    148: 
                    149: 
                    150: /*
                    151:  *  CheckDrawStatus --
                    152:  *
                    153:  *  This function does a check of all buffers being drawn.
                    154:  *
                    155:  *  If it finds an idle pipe, and there is work to be done, it assigns
                    156:  *      a line, and writes out the request.
                    157:  *  If it finds a read-pending pipe, it checks if the read has completed.
                    158:  *      If it has, it is read and a message is sent so the read data can
                    159:  *      be processed.
                    160:  *
                    161:  *  RETURNS
                    162:  *      TRUE        - we did a piece of work
                    163:  *      FALSE       - we could not find any work to do.
                    164:  */
                    165: 
                    166: BOOL CheckDrawStatus( HWND hwnd)
                    167: {
                    168: 
                    169:     static int  iWork = 0;
                    170:     int         iLast;
                    171:     CALCBUF     cb;
                    172:     PDWORD  pbBuf;
                    173: 
                    174:     // If no pipes, forget it
                    175:     if (SvrTableSz == 0)
                    176:         return FALSE;
                    177: 
                    178:     // Move on from where we left off
                    179: 
                    180:     iLast = iWork;
                    181: 
                    182:     while ( TRUE )
                    183:     {
                    184:       iWork++;
                    185: 
                    186:         if (iWork == SvrTableSz)
                    187:             iWork = 0;
                    188: 
                    189:         // Check the status
                    190:         switch(SvrTable[iWork].iStatus) {
                    191: 
                    192:         case SS_PAINTING:
                    193:             break;
                    194: 
                    195:         case SS_IDLE:
                    196:             // Idle; assign it a piece of work
                    197:             if ((long)dwCurrentLine > rclPicture.xRight)
                    198:                 break;
                    199: 
                    200:             if (!fRemoteWork)
                    201:                 break;
                    202:             // cb is of type CALCBUF;
                    203:             // rectangle, precision, threshold and complex point
                    204:             cb.rclDraw.xLeft = dwCurrentLine;
                    205:             cb.rclDraw.xRight = dwCurrentLine + iLines - 1;
                    206:             cb.rclDraw.yTop = rclPicture.yTop;
                    207:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    208:             cb.dblPrecision = dPrecision;
                    209:             cb.dwThreshold = dwThreshold;
                    210:             cb.cptLL = cptLL;
                    211: 
                    212:             SvrTable[iWork].dwLine = dwCurrentLine;
                    213:             dwCurrentLine += iLines;
                    214:             SvrTable[iWork].iStatus = SS_READPENDING;
                    215:             SvrTable[iWork].cPicture = cPictureID;
                    216:             SvrTable[iWork].cLines = iLines;
                    217: 
                    218:             return TRUE;
                    219: 
                    220:         case SS_LOCAL:
                    221:             // Do a chunk of work locally
                    222: 
                    223:             if ((long)dwCurrentLine > rclPicture.xRight) {
                    224:                 if (fContinueZoom == TRUE) {
                    225:                      if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC))
                    226:                         fZoomIn = FALSE;  // start zooming out
                    227:                      if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC))
                    228:                         fZoomIn = TRUE;
                    229:                      if (fZoomIn) {
                    230:                          CountHistogram();
                    231:                          rcZoom.top    = iHistMaxJ * (WIDTH/4);
                    232:                          rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1;
                    233:                          rcZoom.left   = iHistMaxI * (HEIGHT/4);
                    234:                          rcZoom.right  = rcZoom.left + (HEIGHT/4) - 1;
                    235:                          fRectDefined = TRUE;
                    236:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L);
                    237:                      }
                    238:                      else
                    239:                          PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L);
                    240:                 }
                    241:                 break;
                    242:             }
                    243: 
                    244:             if (!TakeDrawBuffer())
                    245:                 break;
                    246: 
                    247:             pbBuf = GetDrawBuffer();
                    248: 
                    249:             cb.rclDraw.xLeft = dwCurrentLine;
                    250:             cb.rclDraw.xRight = dwCurrentLine+ iLines-1;
                    251:             cb.rclDraw.yTop = rclPicture.yTop;
                    252:             cb.rclDraw.yBottom = rclPicture.yBottom;
                    253: 
                    254: 
                    255:             MandelCalc(&cptLL,
                    256:                        &(cb.rclDraw),
                    257:                        dPrecision,
                    258:                        dwThreshold,
                    259:                        (PLINEBUF)pbBuf);
                    260: 
                    261:             FreeDrawBuffer();
                    262: 
                    263:             SvrTable[iWork].cPicture = cPictureID;
                    264:             SvrTable[iWork].dwLine = dwCurrentLine;
                    265:             SvrTable[iWork].cLines = iLines;
                    266: 
                    267:             PostMessage(hwnd, WM_PAINTLINE,
                    268:                             (UINT)iWork,
                    269:                         0L);
                    270:             dwCurrentLine += iLines;
                    271:             return TRUE;
                    272: 
                    273:         }
                    274: 
                    275: 
                    276:         // If we made the full loop, we're done
                    277:         if (iWork == iLast)
                    278:             return FALSE;
                    279:     }
                    280: }
                    281: 
                    282: 
                    283: /*
                    284:  *  SetNewCalc --
                    285:  *
                    286:  *  This sets up new information for a drawing and
                    287:  *  updates the drawing ID so any calculations in progress will not
                    288:  *  be mixed in.
                    289:  */
                    290: 
                    291: void SetNewCalc( CPOINT cptUL, double dPrec, RECT rc)
                    292: {
                    293: 
                    294:     /*
                    295:      *  First, the base point. We need to translate from upper left to
                    296:      *  lower left.
                    297:      */
                    298: 
                    299:     cptLL.real = cptUL.real;
                    300:     cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top));
                    301: 
                    302:     // Now the precision
                    303:     dPrecision = dPrec;
                    304: 
                    305:     // The rectangle. Once again, translate.
                    306:     rclPicture.xLeft = (long) rc.left;
                    307:     rclPicture.xRight = (long) rc.right;
                    308:     rclPicture.yBottom = (long) rc.top;
                    309:     rclPicture.yTop = (long) rc.bottom;
                    310: 
                    311:     // Current line, start of drawing
                    312:     dwCurrentLine = rclPicture.xLeft;
                    313: 
                    314:     dwThreshold = CalcThreshold(dPrecision);
                    315: 
                    316: 
                    317: }
                    318: 
                    319: void IncPictureID(void)
                    320: {
                    321:     cPictureID++;
                    322: }
                    323: 
                    324: /*
                    325:  *  CheckDrawing --
                    326:  *
                    327:  *  Just a sanity check here -- a function to check to make sure that we're
                    328:  *  on the right drawing
                    329:  */
                    330: 
                    331: BOOL
                    332: CheckDrawingID( int id)
                    333: {
                    334:     return (id == cPictureID) ? TRUE : FALSE;
                    335: }
                    336: 
                    337: 
                    338: /*
                    339:  *  TakeDrawBuffer/ GetDrawBuffer/ FreeDrawBuffer / ReturnDrawBuffer
                    340:  *
                    341:  *  These functions hide a handle to a buffer of memory.
                    342:  *
                    343:  *  TakeDrawBuffer ensures only one pipe read at a time.
                    344:  *  GetDrawBuffer locks the handle and returns a pointer.
                    345:  *  FreeDrawBuffer unlocks the handle.
                    346:  *  ReturnDrawBuffer unlocks the handle and lets another pipe read go.
                    347:  */
                    348: 
                    349: static BOOL fBufferTaken = FALSE;
                    350: static HANDLE hSharedBuf = NULL;
                    351: 
                    352: 
                    353: BOOL
                    354: TakeDrawBuffer( void )
                    355: {
                    356: 
                    357:     if (fBufferTaken)
                    358:     {
                    359:         return FALSE;
                    360:     }
                    361: 
                    362:     if (hSharedBuf == NULL)
                    363:     {
                    364:         hSharedBuf = LocalAlloc(LMEM_MOVEABLE, MAX_BUFSIZE);
                    365:         if (hSharedBuf == NULL)
                    366:             return FALSE;
                    367:     }
                    368:     fBufferTaken = TRUE;
                    369:     return TRUE;
                    370: }
                    371: 
                    372: 
                    373: 
                    374: PDWORD
                    375: GetDrawBuffer( void )
                    376: {
                    377: 
                    378:     if (hSharedBuf == NULL)
                    379:         return NULL;
                    380: 
                    381:     return (PDWORD) LocalLock(hSharedBuf);
                    382: }
                    383: 
                    384: 
                    385: 
                    386: void
                    387: FreeDrawBuffer( void )
                    388: {
                    389:     LocalUnlock(hSharedBuf);
                    390: }
                    391: 
                    392: 
                    393: void
                    394: ReturnDrawBuffer( void )
                    395: {
                    396:     fBufferTaken = FALSE;
                    397: }
                    398: 
                    399: 
                    400: 
                    401: /*
                    402:  *  CalcThreshold --
                    403:  *
                    404:  *  We need an iteration threshold beyond which we give up. We want it to
                    405:  *  increase the farther we zoom in. This code generates a threshold value
                    406:  *  based on the precision of drawing.
                    407:  *
                    408:  *  RETURNS
                    409:  *
                    410:  *      threshold calculated based on precision
                    411:  */
                    412: 
                    413: 
                    414: DWORD   CalcThreshold(double precision)
                    415: {
                    416:     DWORD   thres = 25;
                    417:     double  multiplier = (double) 100;
                    418: 
                    419:     /* for every 100, multiply by 2 */
                    420:     while ( (precision *= multiplier) < (double)1)
                    421:         thres *= 2;
                    422: 
                    423:     return thres;
                    424: }
                    425: 
                    426: 
                    427: 
                    428: /*
                    429:  *  QueryThreshold --
                    430:  *
                    431:  *  Callback for finding out what the current drawing's threshold is.
                    432:  */
                    433: 
                    434: DWORD QueryThreshold( void )
                    435: {
                    436:     return dwThreshold;
                    437: }
                    438: 
                    439: 
                    440: /*
                    441:  *
                    442:  *  GetServerCount --
                    443:  *
                    444:  *  Returns the number of servers in the table.
                    445:  */
                    446: 
                    447: int
                    448: GetServerCount( void )
                    449: {
                    450:     return (int) SvrTableSz-1;
                    451: }

unix.superglobalmegacorp.com

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