--- mstools/samples/rpc/mandel/remote.c 2018/08/09 18:20:01 1.1 +++ mstools/samples/rpc/mandel/remote.c 2018/08/09 18:24:14 1.1.1.4 @@ -1,94 +1,73 @@ -/* - * REMOTE.C -- - * - * Code to do the remote calculations for the Windows Mandelbrot Set - * distributed drawing program. - * - * Copyright (C) 1990 Microsoft Corporation. - * - * Information coming into this module (via API calls) is based on - * upper-left being (0,0) (the Windows standard). We translate that - * to PM standard (lower-left is (0,0) ) before we ship it out onto - * the net, and we do reverse translations accordingly. - * - * The iteration data is passed back to the main window procedure - * (by means of a WM_PAINTLINE message) which draws the picture. - * - * A word about the shared buffer: multiple buffers could be used, but - * a single one is used. The buffer is requested in this code, and - * then released after the data has been drawn (in PaintLine() in - * mandel.c). So long as the painting is done quickly, this is efficient. - * - * This code sample is provided for demonstration purposes only. - * Microsoft makes no warranty, either express or implied, - * as to its usability in any given situation. - */ - +/**************************************************************************** + Microsoft RPC Version 1.0 + Copyright Microsoft Corp. 1992 + mandel Example + + FILE: remote.c + + PURPOSE: Client side of the RPC distributed application Mandel + + COMMENTS: Code to do the remote calculations for the Windows + Mandelbrot Set distributed drawing program. + + Information coming into this module (via API calls) is + based on upper-left being (0,0) (the Windows standard). + We translate that to lower-left is (0,0) before we ship + it out onto the net, and we do reverse translations + accordingly. + + The iteration data is passed back to the main window + procedure (by means of a WM_PAINTLINE message) which + draws the picture. + + A word about the shared buffer: multiple buffers could + be used, but a single one is used. The buffer is requested + in this code, and then released after the data has been + drawn (in PaintLine() in mandel.c). So long as the painting + is done quickly, this is efficient. + +****************************************************************************/ -#include +#include #include -#include -#include -#include -#include -#include -#include - +#include #include #ifdef RPC -#include #include "mdlrpc.h" #endif - #include "mandel.h" -/* - * Tuning paramters - */ -#define SVR_TABLE_SZ 20 -#define MAX_PIPENAME_SZ CCHMAXPATH /* - * Manifests, to keep everything neat. + * External variables */ +extern int fBound; +extern svr_table SvrTable; // the server table +extern int iLines; +extern double dPrec; +extern int fContinueZoom; +extern int fZoomIn; +extern int iHistMaxI; +extern int iHistMaxJ; +extern RECT rcZoom; +extern BOOL fRectDefined; -extern int errno; // errno from c runtime /* - * Data structures + * Picture information */ -extern svr_table SvrTable[]; // the table -extern int SvrTableSz; // # of objects in it -char pszFail[255]; - - -// Do we do local work? -BOOL fLocalWork = TRUE; -BOOL fRemoteWork = FALSE; - -static int fDisplay = TRUE; /* display a message box for debug */ +int cPictureID = 0; // picture id, in case we reset in the middle +static CPOINT cptLL; // upper-left +static double dPrecision; // precision of draw +static LONGRECT rclPicture; // rectangle defining client window +static DWORD dwCurrentLine; // next line to be drawn +static DWORD dwThreshold; // threshold for iterations -// Picture information - - int cPictureID = 0; // picture id, in case we reset in the middle -static CPOINT cptLL; // upper-left -static double dPrecision; // precision of draw -static LONGRECT rclPicture; // rectangle defining client window -static DWORD dwCurrentLine; // next line to be drawn -static DWORD dwThreshold; // threshold for iterations - - -static char szLocal[] = "Local machine"; -#ifdef RPC -RPC_STATUS status; // returned by RPC API function -#endif /* - * function prototypes for local procs + * Function prototypes for local procs */ - -DWORD CalcThreshold( double ); - +DWORD CalcThreshold(double); /* @@ -99,51 +78,23 @@ DWORD CalcThreshold( double ); * and it creates the mailslot with which to collect replies to our poll. * * RETURNS - * - * TRUE - initialization succeeded - * FALSE - initialization failed, can't go on + * TRUE - initialization succeeded + * FALSE - initialization failed, can't go on */ - -BOOL -InitRemote( HWND hWnd ) +BOOL InitRemote(HWND hWnd) { + #ifndef RPC UNREFERENCED_PARAMETER(hWnd); #endif // set up our local entry - SvrTableSz++; - strcpy(SvrTable[0].name, szLocal); - SvrTable[0].iStatus = SS_LOCAL; - - // set up remote entries -#ifdef RPC - mdlrpc_ProtocolStack.TransportType = RPC_TRANSPORT_NAMEPIPE; - mdlrpc_ProtocolStack.TransportInfo = "\\device\\namedpipe\\mdlrpc"; - mdlrpc_ProtocolStack.TransportInfoLength = \ - strlen(mdlrpc_ProtocolStack.TransportInfo) + 1; - // add 1 for terminating null - - /* Call the Microsoft RPC V1.0 Alpha API function that lets */ - /* the client establish a connection with the server. */ - /* NOTE: This API function will be replaced in future */ - /* releases by the standard DCE RPC function. */ - status = RpcBindToInterface(&mdlrpc_ProtocolStack, - 0L, - &hMandel); - if (status) { - sprintf(pszFail, "RpcBindToInterface returned 0x%x\n", status); - strcat(pszFail, "Please verify that the server side of the Mandel distributed application is running.\n"); - MessageBox(hWnd, pszFail, "Mandelbrot RPC Server Not Started", - MB_ICONHAND | MB_SYSTEMMODAL); - PostMessage(hWnd, WM_DESTROY, 0, 0L); - return FALSE; - } -#endif + strcpy(SvrTable.name, "Local machine"); + SvrTable.iStatus = SS_LOCAL; // good, we succeeded - return TRUE; + return(TRUE); } @@ -159,123 +110,91 @@ InitRemote( HWND hWnd ) * be processed. * * RETURNS - * TRUE - we did a piece of work - * FALSE - we could not find any work to do. + * TRUE - we did a piece of work + * FALSE - we could not find any work to do. */ -BOOL CheckDrawStatus( HWND hwnd) +BOOL CheckDrawStatus(HWND hwnd) { - - static int iWork = 0; - int iLast; CALCBUF cb; - PDWORD pbBuf; - - // If no pipes, forget it - if (SvrTableSz == 0) - return FALSE; + LPVOID pbBuf; - // Move on from where we left off - - iLast = iWork; - - while ( TRUE ) - { - iWork++; - - if (iWork == SvrTableSz) - iWork = 0; + while(TRUE) { // Check the status - switch(SvrTable[iWork].iStatus) { + switch(SvrTable.iStatus) { case SS_PAINTING: break; case SS_IDLE: - // Idle; assign it a piece of work - if ((long)dwCurrentLine > rclPicture.xRight) - break; - - if (!fRemoteWork) - break; - // cb is of type CALCBUF; - // rectangle, precision, threshold and complex point - cb.rclDraw.xLeft = dwCurrentLine; - cb.rclDraw.xRight = dwCurrentLine + iLines - 1; - cb.rclDraw.yTop = rclPicture.yTop; - cb.rclDraw.yBottom = rclPicture.yBottom; - cb.dblPrecision = dPrecision; - cb.dwThreshold = dwThreshold; - cb.cptLL = cptLL; - - SvrTable[iWork].dwLine = dwCurrentLine; - dwCurrentLine += iLines; - SvrTable[iWork].iStatus = SS_READPENDING; - SvrTable[iWork].cPicture = cPictureID; - SvrTable[iWork].cLines = iLines; - - return TRUE; + break; case SS_LOCAL: // Do a chunk of work locally - if ((long)dwCurrentLine > rclPicture.xRight) { +#ifdef RPC + if (fBound == FALSE) + break; +#endif + + if ((long) dwCurrentLine > rclPicture.xRight) { if (fContinueZoom == TRUE) { - if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC)) + if ((fZoomIn == TRUE) && (dPrec < (double)MINPREC)) fZoomIn = FALSE; // start zooming out - if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC)) + if ((fZoomIn == FALSE) && (dPrec > (double)MAXPREC)) fZoomIn = TRUE; - if (fZoomIn) { - CountHistogram(); - rcZoom.top = iHistMaxJ * (WIDTH/4); - rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1; - rcZoom.left = iHistMaxI * (HEIGHT/4); - rcZoom.right = rcZoom.left + (HEIGHT/4) - 1; - fRectDefined = TRUE; - PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L); - } - else - PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L); + if (fZoomIn) { + CountHistogram(); + rcZoom.top = iHistMaxJ * (WIDTH/4); + rcZoom.bottom = rcZoom.top + (WIDTH/4) - 1; + rcZoom.left = iHistMaxI * (HEIGHT/4); + rcZoom.right = rcZoom.left + (HEIGHT/4) - 1; + fRectDefined = TRUE; + PostMessage(hwnd, WM_COMMAND, IDM_ZOOMIN, 0L); + } + else + PostMessage(hwnd, WM_COMMAND, IDM_ZOOMOUT, 0L); } break; } - if (!TakeDrawBuffer()) + if (TakeDrawBuffer() == FALSE) break; - pbBuf = GetDrawBuffer(); - + pbBuf = LockDrawBuffer(); + cb.rclDraw.xLeft = dwCurrentLine; - cb.rclDraw.xRight = dwCurrentLine+ iLines-1; + cb.rclDraw.xRight = dwCurrentLine + iLines - 1; cb.rclDraw.yTop = rclPicture.yTop; cb.rclDraw.yBottom = rclPicture.yBottom; + RpcTryExcept { + MandelCalc(&cptLL, + &(cb.rclDraw), + dPrecision, + dwThreshold, + (LINEBUF *) pbBuf); + } + RpcExcept(1) { + PostMessage(hwnd, WM_EXCEPTION, 0, 0L); + return(FALSE); + } + RpcEndExcept + + UnlockDrawBuffer(); - MandelCalc(&cptLL, - &(cb.rclDraw), - dPrecision, - dwThreshold, - (PLINEBUF)pbBuf); - - FreeDrawBuffer(); - - SvrTable[iWork].cPicture = cPictureID; - SvrTable[iWork].dwLine = dwCurrentLine; - SvrTable[iWork].cLines = iLines; - - PostMessage(hwnd, WM_PAINTLINE, - (UINT)iWork, - 0L); + SvrTable.cPicture = cPictureID; + SvrTable.dwLine = dwCurrentLine; + SvrTable.cLines = iLines; + + PostMessage(hwnd, WM_PAINTLINE, 0, 0L); dwCurrentLine += iLines; - return TRUE; + return(TRUE); } - - // If we made the full loop, we're done - if (iWork == iLast) - return FALSE; + return(FALSE); } } @@ -288,14 +207,9 @@ BOOL CheckDrawStatus( HWND hwnd) * be mixed in. */ -void SetNewCalc( CPOINT cptUL, double dPrec, RECT rc) +void SetNewCalc(CPOINT cptUL, double dPrec, RECT rc) { - - /* - * First, the base point. We need to translate from upper left to - * lower left. - */ - + // First, translate from upper left to lower left cptLL.real = cptUL.real; cptLL.imag = cptUL.imag - (dPrec * (rc.bottom - rc.top)); @@ -312,15 +226,21 @@ void SetNewCalc( CPOINT cptUL, double dP dwCurrentLine = rclPicture.xLeft; dwThreshold = CalcThreshold(dPrecision); - - } + void IncPictureID(void) { cPictureID++; } + +void ResetPictureID(void) +{ + cPictureID = 0; +} + + /* * CheckDrawing -- * @@ -328,75 +248,68 @@ void IncPictureID(void) * on the right drawing */ -BOOL -CheckDrawingID( int id) +BOOL CheckDrawingID(int id) { - return (id == cPictureID) ? TRUE : FALSE; + return((id == cPictureID) ? TRUE : FALSE); } /* - * TakeDrawBuffer/ GetDrawBuffer/ FreeDrawBuffer / ReturnDrawBuffer - * - * These functions hide a handle to a buffer of memory. - * * TakeDrawBuffer ensures only one pipe read at a time. - * GetDrawBuffer locks the handle and returns a pointer. - * FreeDrawBuffer unlocks the handle. - * ReturnDrawBuffer unlocks the handle and lets another pipe read go. + * LockDrawBuffer locks the handle and returns a pointer. + * UnlockDrawBuffer unlocks the handle. + * ReturnDrawBuffer lets another pipe read go. + * FreeDrawBuffer ensures the allocated buffer is freed upon exit. */ static BOOL fBufferTaken = FALSE; -static HANDLE hSharedBuf = NULL; +static HANDLE hSharedBuf = (HANDLE) NULL; -BOOL -TakeDrawBuffer( void ) +BOOL TakeDrawBuffer(void) { - - if (fBufferTaken) - { - return FALSE; + if (fBufferTaken) { + return(FALSE); } - if (hSharedBuf == NULL) - { + if (hSharedBuf == (HANDLE) NULL) { hSharedBuf = LocalAlloc(LMEM_MOVEABLE, MAX_BUFSIZE); - if (hSharedBuf == NULL) - return FALSE; + if (hSharedBuf == (HANDLE) NULL) + return(FALSE); } + fBufferTaken = TRUE; - return TRUE; + return(TRUE); } - -PDWORD -GetDrawBuffer( void ) +LPVOID LockDrawBuffer(void) { + if (hSharedBuf == (HANDLE) NULL) + return(NULL); - if (hSharedBuf == NULL) - return NULL; - - return (PDWORD) LocalLock(hSharedBuf); + return(LocalLock(hSharedBuf)); } - -void -FreeDrawBuffer( void ) +void UnlockDrawBuffer(void) { LocalUnlock(hSharedBuf); } -void -ReturnDrawBuffer( void ) +void ReturnDrawBuffer(void) { fBufferTaken = FALSE; } +void FreeDrawBuffer(void) +{ + if (hSharedBuf != (HANDLE) NULL) + LocalFree(hSharedBuf); +} + /* * CalcThreshold -- @@ -406,46 +319,30 @@ ReturnDrawBuffer( void ) * based on the precision of drawing. * * RETURNS - * * threshold calculated based on precision */ - -DWORD CalcThreshold(double precision) +DWORD CalcThreshold(double precision) { DWORD thres = 25; - double multiplier = (double) 100; + double multiplier = (double) 100.0; /* for every 100, multiply by 2 */ - while ( (precision *= multiplier) < (double)1) + while ((precision *= multiplier) < (double)1.0) thres *= 2; - return thres; + return(thres); } - /* * QueryThreshold -- * * Callback for finding out what the current drawing's threshold is. */ -DWORD QueryThreshold( void ) +DWORD QueryThreshold(void) { - return dwThreshold; + return(dwThreshold); } - -/* - * - * GetServerCount -- - * - * Returns the number of servers in the table. - */ - -int -GetServerCount( void ) -{ - return (int) SvrTableSz-1; -}