/**************************************************************************** Desc: This routine shuts down all threads in the NLM. ****************************************************************************/ void domEditCleanup( void) { gv_bShutdown = TRUE; while( gv_bRunning) { f_sleep( 10); } }
/**************************************************************************** Desc: After commit and before we unlock, stop and start all indexing. ****************************************************************************/ void flmIndexingAfterCommit( FDB * pDb) { F_BKGND_IX * pStartIx; F_BKGND_IX * pStopIx; F_BKGND_IX * pNextIx; FLMBOOL bThreadsActive; FLMBOOL bStopped; // Signal all background indexing threads in the stop list // to shutdown. Poll until all have terminated. for( ;;) { bThreadsActive = FALSE; for( pStopIx = pDb->pIxStopList; pStopIx; pStopIx = pStopIx->pNext) { stopBackgroundIndexThread( pDb, pStopIx->indexStatus.uiIndexNum, FALSE, &bStopped); if( !bStopped) { bThreadsActive = TRUE; } } if( !bThreadsActive) { break; } f_sleep( 50); } // Now that all of the threads have been stopped, discard the stop list pStopIx = pDb->pIxStopList; pDb->pIxStopList = NULL; for( ; pStopIx; pStopIx = pNextIx) { pNextIx = pStopIx->pNext; f_free( &pStopIx); } // Start threads listed in the index start list. pStartIx = pDb->pIxStartList; pDb->pIxStartList = NULL; for( ; pStartIx; pStartIx = pNextIx) { pNextIx = pStartIx->pNext; (void)flmStartIndexBuild( pDb, pStartIx->indexStatus.uiIndexNum); f_free( &pStartIx); } }
int GEngine::gameLoop() { if (m_errorState == true) { setErrorDetails( "Cannot enter game loop when the engine is in a error state"); return -1; } m_GameActive = true; m_physicsActive = true; m_clock.initialize(); float secondsPassed; while (m_GameActive) { secondsPassed = m_clock.calculateElapsedTime(); //Alert to the FPS calculator of a new frame m_fpsCalculator.frame(secondsPassed); //Run through the postbox and trigger events while (m_inputPostbox.HasNext()) { processEvent(m_inputPostbox.ReadNext()); } doFrameUpdate(secondsPassed); //Rendering Step GRenderer::getRenderer()->renderScene(m_canvasWidth, m_canvasHeight); //End of rendering step //Sleep f_sleep(); } return 0; }
/**************************************************************************** Desc: This routine functions as a thread. It monitors open files and frees up files which have been closed longer than the maximum close time. ****************************************************************************/ FSTATIC RCODE XFLAPI flmCPThread( IF_Thread * pThread) { CP_INFO * pCPInfo = (CP_INFO *)pThread->getParm1(); F_Database * pDatabase = pCPInfo->pDatabase; pThread->setThreadStatus( FLM_THREAD_STATUS_SLEEPING); for (;;) { f_sleep( 1000); if (pDatabase->tryCheckpoint( pThread, pCPInfo)) { break; } } pThread->setThreadStatus( FLM_THREAD_STATUS_TERMINATING); flmFreeCPInfo( &pCPInfo); return( NE_XFLM_OK); }
FINLINE int _sema_timedwait( sema_t * pSem, unsigned int msecs) { int iErr = 0; // If timeout is F_WAITFOREVER, do sem_wait. if( msecs == F_WAITFOREVER) { iErr = _sema_wait( pSem); return( iErr); } for( ;;) { if( (iErr = sema_trywait( pSem)) != 0) { if( iErr == EINTR) { iErr = 0; } f_sleep( f_min( msecs, 10)); msecs -= f_min( msecs, 10); if( !msecs) { iErr = -1; goto Exit; } continue; } } Exit: return( iErr); }
/**************************************************************************** Desc: Thread that will delete block chains from deleted indexes and tables in the background. ****************************************************************************/ RCODE SQFAPI F_Database::maintenanceThread( IF_Thread * pThread) { RCODE rc = NE_SFLM_OK; F_Database * pDatabase = (F_Database *)pThread->getParm1(); F_Db * pDb; F_Row * pRow; FLMUINT64 ui64MaintRowId; FLMBOOL bStartedTrans; FLMBOOL bShutdown; F_DbSystem * pDbSystem; FSTableCursor * pTableCursor; FLMUINT uiBlkAddress; FLMBOOL bIsNull; FLMUINT uiBlocksToFree; FLMUINT uiBlocksFreed; Retry: rc = NE_SFLM_OK; pDb = NULL; pRow = NULL; bStartedTrans = FALSE; bShutdown = FALSE; pDbSystem = NULL; pTableCursor = NULL; if( (pDbSystem = f_new F_DbSystem) == NULL) { rc = RC_SET( NE_SFLM_MEM); goto Exit; } pThread->setThreadStatus( FLM_THREAD_STATUS_INITIALIZING); if( RC_BAD( rc = pDbSystem->internalDbOpen( pDatabase, &pDb))) { // If the file is being closed, this is not an error. if( pDatabase->getFlags() & DBF_BEING_CLOSED) { rc = NE_SFLM_OK; bShutdown = TRUE; } goto Exit; } pDbSystem->Release(); pDbSystem = NULL; if ((pTableCursor = f_new FSTableCursor) == NULL) { rc = RC_SET( NE_SFLM_MEM); goto Exit; } for( ;;) { pThread->setThreadStatus( FLM_THREAD_STATUS_RUNNING); if( RC_BAD( rc = pDb->beginBackgroundTrans( pThread))) { goto Exit; } bStartedTrans = TRUE; pTableCursor->resetCursor(); if (RC_BAD( rc = pTableCursor->setupRange( pDb, SFLM_TBLNUM_BLOCK_CHAINS, 1, FLM_MAX_UINT64, FALSE))) { goto Exit; } // Free up to 25 blocks per transaction. uiBlocksToFree = 25; while (uiBlocksToFree) { if (RC_BAD( rc = pTableCursor->nextRow( pDb, &pRow, &ui64MaintRowId))) { if (rc != NE_SFLM_EOF_HIT) { RC_UNEXPECTED_ASSERT( rc); goto Exit; } rc = NE_SFLM_OK; break; } if (RC_BAD( rc = pRow->getUINT( pDb, SFLM_COLNUM_BLOCK_CHAINS_BLOCK_ADDRESS, &uiBlkAddress, &bIsNull))) { goto Exit; } if (bIsNull) { rc = RC_SET_AND_ASSERT( NE_SFLM_DATA_ERROR); goto Exit; } if( RC_BAD( rc = pDb->maintBlockChainFree( ui64MaintRowId, uiBlkAddress, uiBlocksToFree, 0, &uiBlocksFreed))) { goto Exit; } uiBlocksToFree -= uiBlocksFreed; } bStartedTrans = FALSE; if( RC_BAD( rc = pDb->commitTrans( 0, FALSE))) { goto Exit; } pThread->setThreadStatus( FLM_THREAD_STATUS_SLEEPING); f_semWait( pDatabase->m_hMaintSem, F_WAITFOREVER); if (pThread->getShutdownFlag()) { bShutdown = TRUE; goto Exit; } } Exit: pThread->setThreadStatus( FLM_THREAD_STATUS_TERMINATING); if (pDbSystem) { pDbSystem->Release(); } if (pRow) { pRow->ReleaseRow(); } if( bStartedTrans) { pDb->abortTrans(); } if (pDb) { pDb->Release(); pDb = NULL; } if (!bShutdown) { flmAssert( RC_BAD( rc)); f_sleep( 250); f_semSignal( pDatabase->m_hMaintSem); goto Retry; } return( rc); }
/**************************************************************************** Desc: Stops a background indexing thread Notes: This routine DOES NOT assume that the global mutex is locked. It will lock and unlock the mutex as needed. ****************************************************************************/ FSTATIC void stopBackgroundIndexThread( FDB * pDb, FLMUINT uiIndexNum, FLMBOOL bWait, FLMBOOL * pbStopped) { F_BKGND_IX * pBackgroundIx; FLMUINT uiThreadId; FLMBOOL bMutexLocked = FALSE; if( pbStopped) { *pbStopped = FALSE; } for( ;;) { // Lock the global mutex if( !bMutexLocked) { f_mutexLock( gv_FlmSysData.hShareMutex); bMutexLocked = TRUE; } // Get the background index if( (pBackgroundIx = flmBackgroundIndexGet( pDb->pFile, uiIndexNum, TRUE, &uiThreadId)) == NULL) { if( pbStopped) { *pbStopped = TRUE; } goto Exit; } // Set the thread's shutdown flag first. gv_FlmSysData.pThreadMgr->setThreadShutdownFlag( uiThreadId); // Unlock the global mutex f_mutexUnlock( gv_FlmSysData.hShareMutex); bMutexLocked = FALSE; // The thread may be waiting to start a transaction. pDb->pFile->pFileLockObj->timeoutLockWaiter( uiThreadId); pDb->pFile->pWriteLockObj->timeoutLockWaiter( uiThreadId); if( !bWait) { break; } // Wait for the thread to terminate f_sleep( 50); } Exit: if( bMutexLocked) { f_mutexUnlock( gv_FlmSysData.hShareMutex); } }
bool TestExtMisc::test_sleep() { f_sleep(1); return Count(true); }
/**************************************************************************** Desc: Displays two lines of message and gets the user's input. *****************************************************************************/ FLMUINT gigaGetInput( const char * pszMsg1, const char * pszMsg2, FLMBOOL bMutexLocked) { eColorType eSaveBack; eColorType eSaveFore; FLMUINT uiChar; if (!bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL) { f_mutexLock( gv_hWindowMutex); } // Get the background and foreground color so we can restore them. FTXWinGetBackFore( gv_pWindow, &eSaveBack, &eSaveFore); // Clear the last one or two lines on the screen if (pszMsg2 && *pszMsg2) { FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 2); } else { FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 1); } // Change to WHITE on RED. FTXWinSetBackFore( gv_pWindow, FLM_RED, FLM_WHITE); // Display messages on last two lines of screen. if (pszMsg2 && *pszMsg2) { FTXWinPrintStrXY( gv_pWindow, pszMsg1, 0, gv_uiNumRows - 2); FTXWinPrintStrXY( gv_pWindow, pszMsg2, 0, gv_uiNumRows - 1); } else { FTXWinPrintStrXY( gv_pWindow, pszMsg1, 0, gv_uiNumRows - 1); } // Wait for user to press key. for (;;) { if (gv_bShutdown) { uiChar = 0; break; } if (RC_OK( FTXWinTestKB( gv_pWindow))) { FTXWinInputChar( gv_pWindow, &uiChar); break; } f_sleep(50); } // Clear out last one or two lines of screen. FTXWinSetBackFore( gv_pWindow, eSaveBack, eSaveFore); if (pszMsg2 && *pszMsg2) { FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 2); } else { FTXWinClearXY( gv_pWindow, 0, gv_uiNumRows - 1); } if (!bMutexLocked && gv_hWindowMutex != F_MUTEX_NULL) { f_mutexUnlock( gv_hWindowMutex); } return( uiChar); }
/**************************************************************************** Name: flstMemoryManagerThread Desc: Thread that displays the current status of a database's cache Note: The caller must pass a valid share handle to the thread on startup. *****************************************************************************/ RCODE FTKAPI flstMemoryManagerThread( IF_Thread * pThread) { RCODE rc = NE_XFLM_OK; F_DynamicList * pList = f_new F_DynamicList; FTX_SCREEN * pScreen; FTX_WINDOW * pTitleWin; FTX_WINDOW * pListWin; FTX_WINDOW * pHeaderWin; char szTmpBuf[ 80]; FLMUINT uiLoop; FLMUINT uiIteration = 0; FLMUINT uiScreenCols; FLMUINT uiScreenRows; XFLM_CACHE_INFO CacheInfo; IF_DbSystem * pDbSystem = NULL; #define FMMT_TITLE_HEIGHT 1 #define FMMT_HEADER_HEIGHT 3 if( RC_BAD( FTXScreenInit( "XFlaim Memory Manager", &pScreen))) { goto Exit; } FTXScreenGetSize( pScreen, &uiScreenCols, &uiScreenRows); FTXScreenDisplay( pScreen); if( RC_BAD( FTXWinInit( pScreen, 0, FMMT_TITLE_HEIGHT, &pTitleWin))) { goto Exit; } FTXWinPaintBackground( pTitleWin, FLM_RED); FTXWinPrintStr( pTitleWin, "XFlaim Memory Manager"); FTXWinSetCursorType( pTitleWin, FLM_CURSOR_INVISIBLE); FTXWinOpen( pTitleWin); if( RC_BAD( FTXWinInit( pScreen, uiScreenCols, FMMT_HEADER_HEIGHT, &pHeaderWin))) { goto Exit; } FTXWinSetBackFore( pHeaderWin, FLM_BLUE, FLM_WHITE); FTXWinClear( pHeaderWin); FTXWinPrintf( pHeaderWin, "\n Block Cache Node Cache"); FTXWinSetCursorType( pHeaderWin, FLM_CURSOR_INVISIBLE); FTXWinSetScroll( pHeaderWin, FALSE); FTXWinSetLineWrap( pHeaderWin, FALSE); FTXWinMove( pHeaderWin, 0, FMMT_TITLE_HEIGHT); FTXWinOpen( pHeaderWin); if( RC_BAD( FTXWinInit( pScreen, uiScreenCols, uiScreenRows - FMMT_TITLE_HEIGHT - FMMT_HEADER_HEIGHT, &pListWin))) { goto Exit; } FTXWinMove( pListWin, 0, FMMT_TITLE_HEIGHT + FMMT_HEADER_HEIGHT); FTXWinOpen( pListWin); pList->setup( pListWin); if( RC_BAD( rc = FlmAllocDbSystem( &pDbSystem))) { goto Exit; } uiLoop = 0; while( !gv_bShutdown) { if( !(uiIteration % 100)) { FLMUINT uiKey = 0; XFLM_CACHE_USAGE * pBlkCacheUse = &CacheInfo.BlockCache; XFLM_CACHE_USAGE * pNodeCacheUse = &CacheInfo.NodeCache; pDbSystem->getCacheInfo( &CacheInfo); f_sprintf( szTmpBuf, " Maximum Cache Bytes............... %10u", (unsigned)CacheInfo.uiMaxBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Total Bytes Allocated ............ %10u", (unsigned)CacheInfo.uiTotalBytesAllocated); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Total Bytes....................... %10u %10u", (unsigned)pBlkCacheUse->uiByteCount, (unsigned)pNodeCacheUse->uiByteCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Count ............................ %10u %10u", (unsigned)pBlkCacheUse->uiCount, (unsigned)pNodeCacheUse->uiCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Hits ....................... %10u %10u", (unsigned)pBlkCacheUse->uiCacheHits, (unsigned)pNodeCacheUse->uiCacheHits); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Hit Looks .................. %10u %10u", (unsigned)pBlkCacheUse->uiCacheHitLooks, (unsigned)pNodeCacheUse->uiCacheHitLooks); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Faults ..................... %10u %10u", (unsigned)pBlkCacheUse->uiCacheFaults, (unsigned)pNodeCacheUse->uiCacheFaults); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Fault Looks ................ %10u %10u", (unsigned)pBlkCacheUse->uiCacheFaultLooks, (unsigned)pNodeCacheUse->uiCacheFaultLooks); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Dirty Count ...................... %10u", (unsigned)CacheInfo.uiDirtyCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Dirty Bytes ...................... %10u", (unsigned)CacheInfo.uiDirtyBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " New Count ........................ %10u", (unsigned)CacheInfo.uiNewCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " New Bytes ........................ %10u", (unsigned)CacheInfo.uiNewBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Log Count ........................ %10u", (unsigned)CacheInfo.uiLogCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Log Bytes ........................ %10u", (unsigned)CacheInfo.uiLogBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Old Version Count ................ %10u %10u", (unsigned)pBlkCacheUse->uiOldVerCount, (unsigned)pNodeCacheUse->uiOldVerCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Old Version Bytes ................ %10u %10u", (unsigned)pBlkCacheUse->uiOldVerBytes, (unsigned)pNodeCacheUse->uiOldVerBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Free Count ....................... %10u", (unsigned)CacheInfo.uiFreeCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Free Bytes ....................... %10u", (unsigned)CacheInfo.uiFreeBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Replaceable Count ................ %10u", (unsigned)CacheInfo.uiReplaceableCount); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Replaceable Bytes ................ %10u", (unsigned)CacheInfo.uiReplaceableBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Dynamic Cache Adjust ............. %s", (char *)(CacheInfo.bDynamicCacheAdjust ? "YES" : "NO")); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Adjust Percentage .......... %10u", (unsigned)CacheInfo.uiCacheAdjustPercent); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Adjust Min ................. %10u", (unsigned)CacheInfo.uiCacheAdjustMin); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Cache Adjust Min To Leave ........ %10u", (unsigned)CacheInfo.uiCacheAdjustMinToLeave); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Slabs ............................ %10u %10u", (unsigned)pBlkCacheUse->slabUsage.ui64Slabs, (unsigned)pNodeCacheUse->slabUsage.ui64Slabs); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Slab Bytes ....................... %10u %10u", (unsigned)pBlkCacheUse->slabUsage.ui64SlabBytes, (unsigned)pNodeCacheUse->slabUsage.ui64SlabBytes); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Allocated Cells .................. %10u %10u", (unsigned)pBlkCacheUse->slabUsage.ui64AllocatedCells, (unsigned)pNodeCacheUse->slabUsage.ui64AllocatedCells); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, " Free Cells ....................... %10u %10u", (unsigned)pBlkCacheUse->slabUsage.ui64FreeCells, (unsigned)pNodeCacheUse->slabUsage.ui64FreeCells); pList->update( uiKey++, NULL, szTmpBuf, sizeof( szTmpBuf)); pList->refresh(); } if( RC_OK( FTXWinTestKB( pListWin))) { FLMUINT uiChar; FTXWinInputChar( pListWin, &uiChar); switch( uiChar) { case 'R': case 'r': pDbSystem->resetStats(); break; case FKB_UP: pList->cursorUp(); break; case FKB_DOWN: pList->cursorDown(); break; case FKB_PGUP: pList->pageUp(); break; case FKB_PGDN: pList->pageDown(); break; case FKB_HOME: pList->home(); break; case FKB_END: pList->end(); break; case FKB_ESCAPE: goto Exit; } pList->refresh(); } if( pThread->getShutdownFlag()) { break; } f_sleep( 10); uiIteration++; } Exit: if( pList) { pList->Release(); } if( pScreen) { FTXScreenFree( &pScreen); } if( pDbSystem) { pDbSystem->Release(); } return( rc); }
/**************************************************************************** Name: flstIndexManagerThread Desc: Thread that displays the current status of all indexes in a database Note: The caller must open the database and pass a handle to the thread. The handle will be closed when the thread exits. *****************************************************************************/ RCODE FTKAPI flstIndexManagerThread( IF_Thread * pThread) { RCODE rc = NE_XFLM_OK; F_DynamicList * pList = f_new F_DynamicList; FTX_WINDOW * pTitleWin; FTX_WINDOW * pListWin; FTX_WINDOW * pHeaderWin; FTX_WINDOW * pMsgWin; FLMUINT uiIterations = 0; FLMUINT uiScreenCols; FLMUINT uiScreenRows; FLMUINT uiIndex; FLMUINT uiUpdateInterval; FLMUINT uiLastUpdateTime; IX_DISPLAY_INFO IxDispInfo; IX_DISPLAY_INFO * pDispInfo; DLIST_NODE * pTmpNd; FLMUINT uiKey; FLMBOOL bShowOnline = TRUE; F_Db * pDb = (F_Db *)pThread->getParm1(); FLMUINT uiOneSec; FLMBOOL bScreenLocked = FALSE; IX_Event event; FLMBOOL bRegisteredForEvent = FALSE; IF_DbSystem * pDbSystem = NULL; event.setDispInfo( &IxDispInfo); #define FIMT_TITLE_HEIGHT 1 #define FIMT_HEADER_HEIGHT 4 #define FIMT_LOG_HEIGHT 10 f_memset( &IxDispInfo, 0, sizeof( IX_DISPLAY_INFO)); IxDispInfo.hScreenMutex = F_MUTEX_NULL; IxDispInfo.pDb = (F_Db *)pDb; IxDispInfo.bShowTime = TRUE; if( RC_BAD( f_mutexCreate( &IxDispInfo.hScreenMutex))) { goto Exit; } if( RC_BAD( FTXScreenInit( "Index Manager", &IxDispInfo.pScreen))) { goto Exit; } FTXScreenGetSize( IxDispInfo.pScreen, &uiScreenCols, &uiScreenRows); FTXScreenDisplay( IxDispInfo.pScreen); if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, 0, FIMT_TITLE_HEIGHT, &pTitleWin))) { goto Exit; } FTXWinSetBackFore( pTitleWin, FLM_RED, FLM_WHITE); FTXWinClear( pTitleWin); FTXWinPrintStr( pTitleWin, "FLAIM Index Manager"); FTXWinSetCursorType( pTitleWin, FLM_CURSOR_INVISIBLE); FTXWinOpen( pTitleWin); if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, uiScreenCols, FIMT_HEADER_HEIGHT, &pHeaderWin))) { goto Exit; } FTXWinMove( pHeaderWin, 0, FIMT_TITLE_HEIGHT); FTXWinSetBackFore( pHeaderWin, FLM_BLUE, FLM_WHITE); FTXWinClear( pHeaderWin); FTXWinSetCursorType( pHeaderWin, FLM_CURSOR_INVISIBLE); FTXWinSetScroll( pHeaderWin, FALSE); FTXWinSetLineWrap( pHeaderWin, FALSE); FTXWinOpen( pHeaderWin); if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, uiScreenCols, uiScreenRows - FIMT_TITLE_HEIGHT - FIMT_HEADER_HEIGHT - FIMT_LOG_HEIGHT, &pListWin))) { goto Exit; } FTXWinMove( pListWin, 0, FIMT_TITLE_HEIGHT + FIMT_HEADER_HEIGHT); FTXWinOpen( pListWin); pList->setup( pListWin); if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, uiScreenCols, FIMT_LOG_HEIGHT, &IxDispInfo.pLogWin))) { goto Exit; } FTXWinDrawBorder( IxDispInfo.pLogWin); FTXWinMove( IxDispInfo.pLogWin, 0, uiScreenRows - FIMT_LOG_HEIGHT); FTXWinSetBackFore( IxDispInfo.pLogWin, FLM_BLUE, FLM_WHITE); FTXWinClear( IxDispInfo.pLogWin); FTXWinSetCursorType( IxDispInfo.pLogWin, FLM_CURSOR_INVISIBLE); FTXWinSetScroll( IxDispInfo.pLogWin, TRUE); FTXWinSetLineWrap( IxDispInfo.pLogWin, FALSE); FTXWinOpen( IxDispInfo.pLogWin); if( RC_BAD( rc = FlmAllocDbSystem( &pDbSystem))) { goto Exit; } if (RC_BAD( rc = pDbSystem->registerForEvent( XFLM_EVENT_UPDATES, &event))) { goto Exit; } bRegisteredForEvent = TRUE; FTXWinSetFocus( pListWin); uiIterations = 0; uiUpdateInterval = FLM_SECS_TO_TIMER_UNITS( 1); uiOneSec = FLM_SECS_TO_TIMER_UNITS( 1); uiLastUpdateTime = 0; while( !gv_bShutdown) { FLMUINT uiCurrTime = FLM_GET_TIMER(); if( bScreenLocked) { f_mutexUnlock( IxDispInfo.hScreenMutex); bScreenLocked = FALSE; } if( FLM_ELAPSED_TIME( uiCurrTime, uiLastUpdateTime) >= uiUpdateInterval) { Update_Screen: if( !bScreenLocked) { f_mutexLock( IxDispInfo.hScreenMutex); bScreenLocked = TRUE; } FTXWinSetCursorPos( pHeaderWin, 0, 1); if( IxDispInfo.bShowTime) { FTXWinPrintf( pHeaderWin, "Index Index State Last Rate Keys Documents Time"); } else { FTXWinPrintf( pHeaderWin, "Index Index State Last Rate Keys Documents Trans"); } FTXWinClearToEOL( pHeaderWin); FTXWinPrintf( pHeaderWin, "\n"); FTXWinPrintf( pHeaderWin, "Num. Name DOC"); if (RC_BAD( rc = pDb->transBegin( XFLM_READ_TRANS))) { goto Exit; } pTmpNd = pList->getFirst(); uiIndex = 0; for( ;;) { if( RC_BAD( pDb->indexGetNext( &uiIndex))) { break; } // Remove all invalid entries while( pTmpNd && pTmpNd->uiKey < uiIndex) { uiKey = pTmpNd->uiKey; pTmpNd = pTmpNd->pNext; pList->remove( uiKey); } if (RC_BAD( rc = pDb->indexStatus( uiIndex, &IxDispInfo.IndexStatus))) { goto Exit; } if( !bShowOnline && IxDispInfo.IndexStatus.eState == XFLM_INDEX_ONLINE) { if( pTmpNd && pTmpNd->uiKey == uiIndex) { uiKey = pTmpNd->uiKey; pTmpNd = pTmpNd->pNext; pList->remove( uiKey); } continue; } if( pTmpNd && pTmpNd->uiKey == uiIndex) { FLMUINT uiOldest; FLMUINT uiElapsed; pDispInfo = (IX_DISPLAY_INFO *)pTmpNd->pvData; f_strcpy( IxDispInfo.szName, pDispInfo->szName); // Copy the saved information. f_memcpy( &IxDispInfo.ui64SaveDocsProcessed [0], &pDispInfo->ui64SaveDocsProcessed [0], sizeof( FLMUINT) * MAX_VALS_TO_SAVE); f_memcpy( &IxDispInfo.uiDocSaveTime [0], &pDispInfo->uiDocSaveTime [0], sizeof( FLMUINT) * MAX_VALS_TO_SAVE); uiOldest = IxDispInfo.uiOldestSaved = pDispInfo->uiOldestSaved; // Recalculate the indexing rate. uiCurrTime = FLM_GET_TIMER(); uiElapsed = (uiCurrTime - IxDispInfo.uiDocSaveTime [uiOldest]) / uiOneSec; if (uiElapsed && IxDispInfo.IndexStatus.ui64DocumentsProcessed) { if( IxDispInfo.ui64SaveDocsProcessed[ uiOldest] < IxDispInfo.IndexStatus.ui64DocumentsProcessed) { IxDispInfo.uiIndexingRate = // Records processed in time period (FLMUINT)((IxDispInfo.IndexStatus.ui64DocumentsProcessed - IxDispInfo.ui64SaveDocsProcessed [uiOldest]) / uiElapsed); } else { IxDispInfo.uiIndexingRate = 0; } } else { IxDispInfo.uiIndexingRate = 0; } // Overwrite the oldest with the current data. IxDispInfo.uiDocSaveTime [uiOldest] = uiCurrTime; IxDispInfo.ui64SaveDocsProcessed [uiOldest] = IxDispInfo.IndexStatus.ui64DocumentsProcessed; // Move oldest pointer for next update. if (++IxDispInfo.uiOldestSaved == MAX_VALS_TO_SAVE) { IxDispInfo.uiOldestSaved = 0; } } else { FLMUINT uiLoop; FLMUINT uiBufLen; F_DataVector srchKey; uiCurrTime = FLM_GET_TIMER(); IxDispInfo.uiIndexingRate = 0; for (uiLoop = 0; uiLoop < MAX_VALS_TO_SAVE; uiLoop++) { IxDispInfo.ui64SaveDocsProcessed [uiLoop] = IxDispInfo.IndexStatus.ui64DocumentsProcessed; IxDispInfo.uiDocSaveTime [uiLoop] = uiCurrTime; } IxDispInfo.uiOldestSaved = 0; // Retrieve index name if (RC_BAD( srchKey.setUINT( 0, ELM_INDEX_TAG))) { break; } if (RC_BAD( srchKey.setUINT( 1, uiIndex))) { break; } if (RC_BAD( rc = pDb->keyRetrieve( XFLM_DICT_NUMBER_INDEX, &srchKey, XFLM_EXACT, &srchKey))) { if (rc != NE_XFLM_NOT_FOUND) { break; } } else { F_DOMNode * pNode = NULL; if (RC_BAD( rc = pDb->getNode( XFLM_DICT_COLLECTION, srchKey.getDocumentID(), &pNode))) { if (rc != NE_XFLM_DOM_NODE_NOT_FOUND) { break; } } else { uiBufLen = sizeof( IxDispInfo.szName); rc = pNode->getAttributeValueUTF8( pDb, ATTR_NAME_TAG, (FLMBYTE *)IxDispInfo.szName, uiBufLen); pNode->Release(); if (rc != NE_XFLM_OK && rc != NE_XFLM_DOM_NODE_NOT_FOUND && rc != NE_XFLM_CONV_DEST_OVERFLOW) { break; } } } } pList->update( uiIndex, ixDisplayHook, &IxDispInfo, sizeof( IxDispInfo)); pList->refresh(); if( pTmpNd && pTmpNd->uiKey == uiIndex) { pTmpNd = pTmpNd->pNext; } } pDb->transAbort(); uiLastUpdateTime = FLM_GET_TIMER(); pList->refresh(); } if( !bScreenLocked) { f_mutexLock( IxDispInfo.hScreenMutex); bScreenLocked = TRUE; } if( RC_OK( FTXWinTestKB( pListWin))) { FLMUINT uiChar; FTXWinInputChar( pListWin, &uiChar); f_mutexUnlock( IxDispInfo.hScreenMutex); bScreenLocked = FALSE; switch( uiChar) { case 'O': case 'o': { bShowOnline = !bShowOnline; goto Update_Screen; } case '+': case 'r': { if( (pTmpNd = pList->getCurrent()) != NULL) { if (RC_BAD( rc = pDb->indexResume( pTmpNd->uiKey))) { goto Exit; } goto Update_Screen; } break; } case 's': { if( (pTmpNd = pList->getCurrent()) != NULL) { if (RC_BAD( rc = pDb->indexSuspend( pTmpNd->uiKey))) { goto Exit; } goto Update_Screen; } break; } case FKB_ALT_S: case 'S': { f_mutexLock( IxDispInfo.hScreenMutex); FTXMessageWindow( IxDispInfo.pScreen, FLM_RED, FLM_WHITE, "Suspending all indexes ....", NULL, &pMsgWin); f_mutexUnlock( IxDispInfo.hScreenMutex); if (RC_OK( pDb->transBegin( XFLM_UPDATE_TRANS))) { uiIndex = 0; for( ;;) { if( RC_BAD( pDb->indexGetNext( &uiIndex))) { break; } if (RC_BAD( pDb->indexSuspend( uiIndex))) { break; } } if (RC_BAD( pDb->transCommit())) { (void)pDb->transAbort(); } } if( pMsgWin) { f_mutexLock( IxDispInfo.hScreenMutex); FTXWinFree( &pMsgWin); f_mutexUnlock( IxDispInfo.hScreenMutex); } goto Update_Screen; } case 'R': case FKB_ALT_R: { f_mutexLock( IxDispInfo.hScreenMutex); FTXMessageWindow( IxDispInfo.pScreen, FLM_RED, FLM_WHITE, "Resuming all indexes ", NULL, &pMsgWin); f_mutexUnlock( IxDispInfo.hScreenMutex); if (RC_OK( pDb->transBegin( XFLM_UPDATE_TRANS))) { uiIndex = 0; for( ;;) { if( RC_BAD( pDb->indexGetNext( &uiIndex))) { break; } if (RC_BAD( pDb->indexResume( uiIndex))) { break; } } if (RC_BAD( pDb->transCommit())) { (void)pDb->transAbort(); break; } } if( pMsgWin) { f_mutexLock( IxDispInfo.hScreenMutex); FTXWinFree( &pMsgWin); f_mutexUnlock( IxDispInfo.hScreenMutex); } goto Update_Screen; } case 'T': case 't': { IxDispInfo.bShowTime = !IxDispInfo.bShowTime; goto Update_Screen; } case '?': { FTX_WINDOW * pHelpWin = NULL; FTX_WINDOW * pHelpTitle = NULL; F_DynamicList * pHelpList = NULL; FLMUINT uiItem = 0; char szTmpBuf [100]; f_mutexLock( IxDispInfo.hScreenMutex); bScreenLocked = TRUE; if( (pHelpList = f_new F_DynamicList) == NULL) { goto Help_Exit; } if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, uiScreenCols, 1, &pHelpTitle))) { goto Help_Exit; } FTXWinSetBackFore( pHelpTitle, FLM_RED, FLM_WHITE); FTXWinClear( pHelpTitle); FTXWinSetCursorType( pHelpTitle, FLM_CURSOR_INVISIBLE); FTXWinSetScroll( pHelpTitle, FALSE); FTXWinSetLineWrap( pHelpTitle, FALSE); FTXWinPrintf( pHelpTitle, "FLAIM Index Manager - Help"); FTXWinOpen( pHelpTitle); if( RC_BAD( FTXWinInit( IxDispInfo.pScreen, uiScreenCols, uiScreenRows - 1, &pHelpWin))) { goto Help_Exit; } FTXWinDrawBorder( pHelpWin); FTXWinOpen( pHelpWin); pHelpList->setup( pHelpWin); f_sprintf( szTmpBuf, "R, ALT_R Resume all indexes"); pHelpList->update( ++uiItem, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, "S, ALT_S Suspend all indexes"); pHelpList->update( ++uiItem, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, "o, O Toggle display of on-line indexes"); pHelpList->update( ++uiItem, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, "+, r Resume selected index with auto on-line option"); pHelpList->update( ++uiItem, NULL, szTmpBuf, sizeof( szTmpBuf)); f_sprintf( szTmpBuf, "s Suspend selected index"); pHelpList->update( ++uiItem, NULL, szTmpBuf, sizeof( szTmpBuf)); pHelpList->refresh(); pHelpWin = pHelpList->getListWin(); f_mutexUnlock( IxDispInfo.hScreenMutex); bScreenLocked = FALSE; while( !gv_bShutdown) { f_mutexLock( IxDispInfo.hScreenMutex); bScreenLocked = TRUE; if( RC_OK( FTXWinTestKB( pHelpWin))) { FLMUINT uiTmpChar; FTXWinInputChar( pHelpWin, &uiTmpChar); if( uiTmpChar == FKB_ESCAPE) { break; } pHelpList->defaultKeyAction( uiTmpChar); } f_mutexUnlock( IxDispInfo.hScreenMutex); bScreenLocked = FALSE; f_sleep( 10); } Help_Exit: if( !bScreenLocked) { f_mutexLock( IxDispInfo.hScreenMutex); bScreenLocked = TRUE; } if( pHelpList) { pHelpList->Release(); } if( pHelpTitle) { FTXWinFree( &pHelpTitle); } f_mutexUnlock( IxDispInfo.hScreenMutex); bScreenLocked = FALSE; break; } case FKB_ESCAPE: { goto Exit; } default: { f_mutexLock( IxDispInfo.hScreenMutex); pList->defaultKeyAction( uiChar); f_mutexUnlock( IxDispInfo.hScreenMutex); break; } } f_mutexLock( IxDispInfo.hScreenMutex); pList->refresh(); f_mutexUnlock( IxDispInfo.hScreenMutex); } uiIterations++; if( pThread->getShutdownFlag()) { break; } f_sleep( 1); } Exit: if( pList) { pList->Release(); } if (bRegisteredForEvent) { pDbSystem->deregisterForEvent( XFLM_EVENT_UPDATES, &event); } if( IxDispInfo.pScreen) { FTXScreenFree( &IxDispInfo.pScreen); } if( IxDispInfo.hScreenMutex != F_MUTEX_NULL) { f_mutexDestroy( &IxDispInfo.hScreenMutex); } if( pDb != NULL) { pDb->Release(); } if( pDbSystem) { pDbSystem->Release(); } return( rc); }
/**************************************************************************** Name: UIMain ****************************************************************************/ void UIMain( void * pData) { F_Db * pDb = NULL; FTX_SCREEN * pScreen = NULL; FTX_WINDOW * pTitleWin = NULL; F_DomEditor * pDomEditor = NULL; char szTitle[ 80]; FLMUINT uiDummy; char szDbPath [F_PATH_MAX_SIZE]; FLMUINT Cols; FLMUINT Rows; RCODE rc; int iResCode = 0; F_UNREFERENCED_PARM( pData); if( RC_BAD( dbSystem.init())) { iResCode = -1; goto Exit; } f_sprintf( szTitle, "DOMEdit for XFLAIM [DB=%s/BUILD=%s]", XFLM_CURRENT_VER_STR, __DATE__); if( RC_BAD( FTXInit( szTitle, 80, 50, FLM_BLUE, FLM_WHITE, NULL, NULL))) { iResCode = 1; goto Exit; } FTXSetShutdownFlag( gv_pFtxInfo, &gv_bShutdown); if( FTXScreenInit( gv_pFtxInfo, szTitle, &pScreen) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } if( FTXWinInit( pScreen, 0, 1, &pTitleWin) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } if( FTXWinPaintBackground( pTitleWin, FLM_RED) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } if( FTXWinPrintStr( pTitleWin, szTitle) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } FTXWinSetCursorType( pTitleWin, FLM_CURSOR_INVISIBLE); if( FTXWinOpen( pTitleWin) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } if( RC_BAD( pThreadMgr->createThread( &gv_pBackgroundThrd, _domEditBackgroundThread, "domedit_refresh"))) { iResCode = 1; goto Exit; } /* Check expiration date */ if( RC_BAD( rc = domEditVerifyRun())) { FTXDisplayMessage( pScreen, FLM_RED, FLM_WHITE, "This Utility Has Expired", "NE_XFLM_ILLEGAL_OP", &uiDummy); f_sleep( 5000); iResCode = 1; goto Exit; } /* Open the database */ if( gv_szDbPath[ 0]) { if( RC_BAD( rc = dbSystem.dbOpen( gv_szDbPath, NULL, gv_szRflDir, (IF_Db **)&pDb, gv_szPassword, gv_bAllowLimited))) { char szErr [20]; f_sprintf( szErr, "Error=0x%04X", (unsigned)rc); FTXDisplayMessage( pScreen, FLM_RED, FLM_WHITE, "Unable to open the database", szErr, &uiDummy); iResCode = 1; goto Exit; } } else { if( RC_BAD( rc = dbSystem.dbOpen( szDbPath, NULL, gv_szRflDir, (IF_Db **)&pDb, gv_szPassword, gv_bAllowLimited))) { char szErr [20]; f_sprintf( szErr, "Error=0x%04X", (unsigned)rc); FTXDisplayMessage( pScreen, FLM_RED, FLM_WHITE, "Unable to open the database", szErr, &uiDummy); iResCode = 1; goto Exit; } else { FTXWinClear( pTitleWin); if( FTXWinPrintf( pTitleWin, "%s (Direct)", szTitle) != FTXRC_SUCCESS) { iResCode = 1; goto Exit; } } } if( (pDomEditor = f_new F_DomEditor) == NULL) { iResCode = 1; goto Exit; } if( RC_BAD( pDomEditor->Setup( pScreen))) { iResCode = 1; goto Exit; } pDomEditor->setSource( pDb, XFLM_DATA_COLLECTION); pDomEditor->setShutdown( &gv_bShutdown); /* Fire up the editor */ FTXScreenGetSize( pScreen, &Cols, &Rows); pDomEditor->interactiveEdit( 0, 1, Cols - 1, Rows - 1); Exit: if( pDomEditor) { pDomEditor->Release(); pDomEditor = NULL; } gv_bShutdown = TRUE; if (pDb) { pDb->Release(); } if( gv_pBackgroundThread) { gv_pBackgroundThrd->Release(); } if( pThreadMgr) { pThreadMgr->Release(); } dbSystem.exit(); }