static void ThreadFuncDedicatedDataset(void* _psThreadDescription) { ThreadDescription* psThreadDescription = (ThreadDescription*)_psThreadDescription; int nXSize = psThreadDescription->poDS->GetRasterXSize(); int nYSize = psThreadDescription->poDS->GetRasterYSize(); void* pBuffer = CPLMalloc(psThreadDescription->nBufferSize); while( psThreadDescription->psRequestList != NULL ) { Request* psRequest = GetNextRequest(psThreadDescription->psRequestList); ReadRaster(psThreadDescription->poDS, nXSize, nYSize, psRequest->nBands, (GByte*)pBuffer, psRequest->nXOff, psRequest->nYOff, psRequest->nXWin, psRequest->nYWin); CPLFree(psRequest); } CPLFree(pBuffer); }
static void ThreadFuncWithMigration(void* /* _unused */) { Request* psRequest; while( (psRequest = GetNextRequest(psGlobalRequestList)) != NULL ) { Resource* psResource = AcquireFirstResource(); assert(psResource); int nXSize = psResource->poDS->GetRasterXSize(); int nYSize = psResource->poDS->GetRasterYSize(); ReadRaster(psResource->poDS, nXSize, nYSize, psRequest->nBands, (GByte*)psResource->pBuffer, psRequest->nXOff, psRequest->nYOff, psRequest->nXWin, psRequest->nYWin); CPLFree(psRequest); PutResourceAtEnd(psResource); } }
void EHSServer::HandleData ( int inTimeoutMilliseconds, ///< milliseconds for timeout on select pthread_t inThreadId ///< numeric ID for this thread to help debug ) { //fprintf ( stderr, "##### [%d] Trying to lock server mutex\n", inThreadId ); MUTEX_LOCK ( m_oMutex ); //fprintf ( stderr, "##### [%d] Got lock on server mutex\n", inThreadId ); // determine if there are any jobs waiting if this thread should -- // if we're running one-thread-per-request and this is the accept thread // we don't look for requests HttpRequest * poHttpRequest = NULL; if ( m_nServerRunningStatus != SERVERRUNNING_ONETHREADPERREQUEST || !pthread_equal(inThreadId,m_nAcceptThreadId) ) { poHttpRequest = GetNextRequest ( ); } // if we got a request to handle if ( poHttpRequest != NULL ) { //fprintf ( stderr, "##### [%d] Got a request to handle\n", inThreadId ); // handle the request and post it back to the connection object MUTEX_UNLOCK ( m_oMutex ); // route the request HttpResponse * poHttpResponse = m_poTopLevelEHS->RouteRequest ( poHttpRequest ); // add the response to the appropriate connection's response list poHttpResponse->m_poEHSConnection->AddResponse ( poHttpResponse ); delete poHttpRequest; } // otherwise, no requests are pending else { // if something is already accepting, sleep if ( m_nAccepting ) { // wait until something happens // it's ok to not recheck our condition here, as we'll come back in the same way and recheck then //fprintf ( stderr, "##### [%d] Sleeping because no requests and someone else is accepting\n", inThreadId ); pthread_cond_wait ( & m_oDoneAccepting, & m_oMutex ); MUTEX_UNLOCK ( m_oMutex ); } // if no one is accepting, we accept else { m_nAcceptedNewConnection = 0; //fprintf ( stderr, "Accepting\n" ); // we're now accepting m_nAccepting = 1; MUTEX_UNLOCK ( m_oMutex ); // create the FD set for poll CreateFdSet(); int nSocketCount = poll( m_oReadFds.GetFdArray(), m_oReadFds.GetFdCount(), inTimeoutMilliseconds ); // handle select error #ifdef _WIN32 if ( nSocketCount == SOCKET_ERROR ) #else // NOT _WIN32 if ( nSocketCount == -1 ) #endif // _WIN32 { EHS_TRACE ( "[%d] Critical Error: select() failed. Aborting\n", inThreadId ); // Idea! Remove stupid idea //exit ( 0 ); } // if no sockets have data to read, clear accepting flag and return if ( nSocketCount > 0 ) { // Check the accept socket for a new connection CheckAcceptSocket ( ); // check client sockets for data CheckClientSockets ( ); } MUTEX_LOCK ( m_oMutex ); ClearIdleConnections ( ); m_nAccepting = 0; MUTEX_UNLOCK ( m_oMutex ); // Occasional pulse for updating of things m_poTopLevelEHS->HttpPulse (); } // END ACCEPTING } // END NO REQUESTS PENDING MUTEX_LOCK ( m_oMutex ); // Delete unused connections after all threads have been synced EHSConnectionList :: iterator iter = m_oEHSConnectionUnusedList.begin (); while ( iter != m_oEHSConnectionUnusedList.end () ) { EHSConnection* pConnection = *iter; // Delete it after all threads are past syncing point if ( pConnection->m_UnusedSyncId < m_ThreadsSyncPoint.GetSyncId () - 1 ) { iter = m_oEHSConnectionUnusedList.erase ( iter ); delete pConnection; } else iter++; } MUTEX_UNLOCK ( m_oMutex ); }
VOID SerialTryToCompleteCurrent( IN PSERIAL_DEVICE_EXTENSION Extension, IN PFN_WDF_INTERRUPT_SYNCHRONIZE SynchRoutine OPTIONAL, IN NTSTATUS StatusToUse, IN WDFREQUEST *CurrentOpRequest, IN WDFQUEUE QueueToProcess OPTIONAL, IN WDFTIMER IntervalTimer OPTIONAL, IN WDFTIMER TotalTimer OPTIONAL, IN PSERIAL_START_ROUTINE Starter OPTIONAL, IN PSERIAL_GET_NEXT_ROUTINE GetNextRequest OPTIONAL, IN LONG RefType ) /*++ Routine Description: This routine attempts to remove all of the reasons there are references on the current read/write. If everything can be completed it will complete this read/write and try to start another. NOTE: This routine assumes that it is called with the cancel spinlock held. Arguments: Extension - Simply a pointer to the device extension. SynchRoutine - A routine that will synchronize with the isr and attempt to remove the knowledge of the current request from the isr. NOTE: This pointer can be null. IrqlForRelease - This routine is called with the cancel spinlock held. This is the irql that was current when the cancel spinlock was acquired. StatusToUse - The request's status field will be set to this value, if this routine can complete the request. Return Value: None. --*/ { PREQUEST_CONTEXT reqContext; ASSERTMSG("SerialTryToCompleteCurrent: CurrentOpRequest is NULL", *CurrentOpRequest); reqContext = SerialGetRequestContext(*CurrentOpRequest); if(RefType == SERIAL_REF_ISR || RefType == SERIAL_REF_XOFF_REF) { // // We can decrement the reference to "remove" the fact // that the caller no longer will be accessing this request. // SERIAL_CLEAR_REFERENCE( reqContext, RefType ); } if (SynchRoutine) { WdfInterruptSynchronize( Extension->WdfInterrupt, SynchRoutine, Extension ); } // // Try to run down all other references to this request. // SerialRundownIrpRefs( CurrentOpRequest, IntervalTimer, TotalTimer, Extension, RefType ); if(StatusToUse == STATUS_CANCELLED) { // // This function is called from a cancelroutine. So mark // the request as cancelled. We need to do this because // we may not complete the request below if somebody // else has a reference to it. // This state variable was added to avoid calling // WdfRequestMarkCancelable second time on a request that // has cancelled but wasn't completed in the cancel routine. // reqContext->Cancelled = TRUE; } // // See if the ref count is zero after trying to complete everybody else. // if (!SERIAL_REFERENCE_COUNT(reqContext)) { WDFREQUEST newRequest; // // The ref count was zero so we should complete this // request. // // The following call will also cause the current request to be // completed. // reqContext->Status = StatusToUse; if (StatusToUse == STATUS_CANCELLED) { reqContext->Information = 0; } if (GetNextRequest) { GetNextRequest( CurrentOpRequest, QueueToProcess, &newRequest, TRUE, Extension ); if (newRequest) { Starter(Extension); } } else { WDFREQUEST oldRequest = *CurrentOpRequest; // // There was no get next routine. We will simply complete // the request. We should make sure that we null out the // pointer to the pointer to this request. // *CurrentOpRequest = NULL; SerialCompleteRequest(oldRequest, reqContext->Status, reqContext->Information); } } else { } }