Annotation of mstools/samples/rpc/mandel/remote.c, revision 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.