VOID SysRWMutexUnlockRead(PRWMTX psRWMtx) { SysMutexLock( psRWMtx->hMtx ); if ( psRWMtx->ulReadLocks > 0 ) psRWMtx->ulReadLocks--; SysMutexUnlock( psRWMtx->hMtx ); SysEventPost( psRWMtx->hEV ); }
///////////////////////////////////////////////////////////////////////////// // // FUNCTION: fnPopMsgQ_State // // PURPOSE: This routine pops the state of the message queue object // ///////////////////////////////////////////////////////////////////////////// zLONG fnPopMsgQ_State( zVIEW vMsgQ ) { zPCHAR pStack; // blob containing Status Stack zLONG lPrevState = 0; zUSHORT uCnt; #ifdef zREMOTE_SERVER // Protect this with a semaphore!!! SysMutexLock( vSubtask, "ZDm", 0, 0 ); // TraceLineS( "PopMsgQ_State Lock Mutex ZDm", "" ); #endif GetAddrForAttribute( (zPCHAR *) &pStack, vMsgQ, szlTask, szlStatus ); if ( pStack ) { uCnt = *((zPSHORT) (pStack + sizeof( zLONG ))); if ( uCnt > 0 ) { uCnt--; *((zPSHORT) (pStack + sizeof( zLONG ))) = uCnt; } else { OperatorSend( 0, szlDrvr, "Cannot pop message queue", TRUE ); } if ( uCnt ) { lPrevState = *((zPLONG) (pStack + // sizeof( zLONG ) + the extra long is in uCnt 2 * sizeof( zSHORT ) + uCnt * sizeof( zLONG ))); } else lPrevState = 0; *((zPLONG) pStack) = lPrevState; } else { TraceLineS( "PopMsgQ_State Lock Mutex ZDm: ", "NULL Status?" ); DisplayObjectInstance( vMsgQ, 0, 0 ); ::MessageBox( 0, "PushMsgQ_State NULL Status?", "ZDr Error", MB_OK ); } #ifdef zREMOTE_SERVER // TraceLineS( "PopMsgQ_State Unlock Mutex ZDm", "" ); SysMutexUnlock( vSubtask, "ZDm", 0 ); #endif return( lPrevState ); }
VOID SysRWMutexLockWrite(PRWMTX psRWMtx) { while( 1 ) { SysMutexLock( psRWMtx->hMtx ); if ( psRWMtx->ulReadLocks == 0 ) break; SysMutexUnlock( psRWMtx->hMtx ); SysEventWait( psRWMtx->hEV, SEM_INDEFINITE_WAIT ); SysEventReset( psRWMtx->hEV ); } }
VOID SysRWMutexLockRead(PRWMTX psRWMtx) { SysMutexLock( psRWMtx->hMtx ); psRWMtx->ulReadLocks++; SysMutexUnlock( psRWMtx->hMtx ); }
///////////////////////////////////////////////////////////////////////////// // // FUNCTION: fnPushMsgQ_State // // PURPOSE: This routine sets the state of the message queue object // and pushes the state on the stack. The stack is organized // as follows: // // zLONG lCurrentState; // zSHORT nEntryCnt; // zSHORT nEntryMax; // zLONG lState[ 1 ]; // zLONG lState[ 2 ]; // . // . // . // // zLONG lState[ n ]; // same as lCurrentState // ///////////////////////////////////////////////////////////////////////////// void fnPushMsgQ_State( zVIEW vMsgQ, zLONG lState ) { zPCHAR pStack; // blob containing Status Stack zUSHORT uCnt; zUSHORT uMax; #ifdef zREMOTE_SERVER // Protect this with a semaphore!!! SysMutexLock( vSubtask, "ZDm", 0, 0 ); // TraceLineS( "PushMsgQ_State Lock Mutex ZDm", "" ); // DisplayObjectInstance( vMsgQ, 0, 0 ); // ::MessageBox( 0, "PushMsgQ", "ZDr", MB_OK ); #endif GetAddrForAttribute( (zPCHAR *) &pStack, vMsgQ, szlTask, szlStatus ); if ( pStack ) { uCnt = *((zPSHORT) (pStack + sizeof( zLONG ))); uMax = *((zPSHORT) (pStack + sizeof( zLONG ) + sizeof( zSHORT ))); // If there is no more room on the stack ... make more room. if ( uCnt >= uMax ) { zULONG ulBlobLth; zULONG ulLth; uMax += 10; ulLth = sizeof( zLONG ) + 2 * sizeof( zSHORT ) + uMax * sizeof( zLONG ); ulBlobLth = ulLth; zPCHAR pch = new char[ ulLth ]; GetBlobFromAttribute( pch, &ulBlobLth, vMsgQ, szlTask, szlStatus ); if ( ulLth != ulBlobLth + 10 * sizeof( zLONG ) ) OperatorSend( 0, szlDrvr, "PushMsgQ_State", TRUE ); else TraceLineI( "Message queue stack expanded to ", ulLth ); SetAttributeFromBlob( vMsgQ, szlTask, szlStatus, pch, ulLth ); GetAddrForAttribute( (zPCHAR *) &pStack, vMsgQ, szlTask, szlStatus ); *((zPSHORT) (pStack + sizeof( zLONG ) + sizeof( zSHORT ))) = uMax; delete [] pch; } (*((zPSHORT) (pStack + sizeof( zLONG ))))++; // increment EntryCnt *((zPLONG) pStack) = lState; // set CurrentState *((zPLONG) (pStack + sizeof( zLONG ) + // set State[ n ] 2 * sizeof( zSHORT ) + uCnt * sizeof( zLONG ))) = lState; // (not incrementing // uCnt since not // used hereafter) } else { TraceLineS( "PushMsgQ_State Lock Mutex ZDm: ", "NULL Status?" ); DisplayObjectInstance( vMsgQ, 0, 0 ); ::MessageBox( 0, "PushMsgQ_State NULL Status?", "ZDr Error", MB_OK ); } #ifdef zREMOTE_SERVER // TraceLineS( "PushMsgQ_State Unlock Mutex ZDm", "" ); SysMutexUnlock( vSubtask, "ZDm", 0 ); #endif }