u4 mythreadproc(AThread& thread) { CommonData *pData = static_cast<CommonData *>(thread.getParameter()); AASSERT(NULL, pData); u4 id = thread.getId(); thread.setRunning(true); { { ALock lock(pData->m_cs); pData->m_count++; } { ALock lock(g_ConsoleOutput); std::cout << "[" << AString::fromU4(thread.getId()) << "," << pData->m_count << "]" << std::flush; } AThread::sleep(300); } thread.setRunning(false); return 0; }
u4 threadProc(AThread& thread) { std::cout << "Thread started." << std::endl; while (!thread.hasFlag(ATHREAD_STOP)) { if (thread.hasFlag(ATHREAD_PAUSE)) { //a_Thread paused, wake up to see flag settings AThread::sleep(500); } else { u4 *piter = (u4 *)thread.getParameter(); (*piter)++; AThread::sleep(1000); } } std::cout << "Thread exited." << std::endl; return 1; }
u4 AOSContextQueue_IsAvailable::_threadprocWorker(AThread& thread) { AOSContextQueue_IsAvailable::QueueWithThread *pThis = dynamic_cast<AOSContextQueue_IsAvailable::QueueWithThread *>(thread.getThis()); AOSContextQueue_IsAvailable *pOwner = dynamic_cast<AOSContextQueue_IsAvailable *>(thread.getParameter()); AASSERT(&thread, pThis); AASSERT(&thread, pOwner); timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; thread.setRunning(true); fd_set sockSet; while (thread.isRun()) { try { if (pThis->queue.size() > 0) { FD_ZERO(&sockSet); int count = 0; // Convert to ABasePtrQueue ABase *p = pThis->queue.useHead(); while (count < FD_SETSIZE && p) { AOSContext *pContext = (AOSContext *)p; FD_SET((SOCKET)pContext->useSocket().getSocketInfo().m_handle, &sockSet); ++count; p = p->useNext(); } if (count > 0) { int availCount = ::select(count, &sockSet, NULL, NULL, &timeout); if (availCount > 0) { int count2 = 0; p = pThis->queue.useHead(); while (availCount > 0 && count2 <= count && p) { AOSContext *pContext = (AOSContext *)p; p = p->useNext(); if (FD_ISSET(pContext->useSocket().getSocketInfo().m_handle, &sockSet)) { pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_ISAVAILABLE_SELECT_SET); //a_Attempt to read some data to check if it actually has data, if not then connection is closed size_t bytesRead = AConstant::npos; try { bytesRead = pContext->useSocket().readBlockIntoLookahead(); if (!bytesRead || AConstant::npos == bytesRead) { //a_No data to read, socket is closed pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_IS_SOCKET_CLOSED); pContext->useEventVisitor().startEvent(ASW("AOSContextQueue_IsAvailable: Detected closed remote socket",58), AEventVisitor::EL_WARN); pContext->useSocket().close(); { ALock lock(pThis->sync); pThis->queue.remove(pContext); } pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext); } else if (AConstant::unavail == bytesRead) { // Would block, keep waiting if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout) { AString str; str.append("AOSContextQueue_IsAvailable: No data (non-blocking) after timeout: ",67); pContext->useTimeoutTimer().emit(str); //a_We are done with this request, still no data pContext->useEventVisitor().startEvent( str, (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR) ); { ALock lock(pThis->sync); pThis->queue.remove(pContext); } pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext); } } else { //a_Add to next queue pContext->useConnectionFlags().setBit(AOSContext::CONFLAG_ISAVAILABLE_PENDING); if (pContext->useEventVisitor().isLogging(AEventVisitor::EL_DEBUG)) pContext->useEventVisitor().startEvent(ASW("AOSContextQueue_IsAvailable: HTTP header has more data",54), AEventVisitor::EL_DEBUG); { ALock lock(pThis->sync); pThis->queue.remove(pContext); } pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_PRE_EXECUTE, &pContext); } } catch(AException e) { bytesRead = AConstant::npos; //a_Following switch will handle this ARope rope("AOSContextQueue_IsAvailable: Exception reading from socket",58); rope.append(e); pContext->useEventVisitor().addEvent(rope, AEventVisitor::EL_ERROR); } --availCount; } else { //a_Select called on this AOSContext and no data available if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout) { AString str; str.append("AOSContextQueue_IsAvailable: No data after timeout: ",52); pContext->useTimeoutTimer().emit(str); //a_We are done with this request, still no data pContext->useEventVisitor().startEvent( str, (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR) ); { ALock lock(pThis->sync); pThis->queue.remove(pContext); } pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext); } } ++count2; } AASSERT(pOwner, !availCount); } else { //a_Nothing has data, flag them all p = pThis->queue.useHead(); while (p) { AOSContext *pContext = (AOSContext *)p; p = p->useNext(); if (pContext->useTimeoutTimer().getInterval() > pOwner->m_NoDataTimeout) { AString str("AOSContextQueue_IsAvailable: No data after timeout: ",52); pContext->useTimeoutTimer().emit(str); //a_We are done with this request, still no data ALock lock(pThis->sync); pContext->useEventVisitor().startEvent( str, (pContext->useConnectionFlags().isSet(AOSContext::CONFLAG_IS_HTTP11_PIPELINING) ? AEventVisitor::EL_EVENT : AEventVisitor::EL_ERROR) ); pThis->queue.remove(pContext); pOwner->m_Services.useContextManager().changeQueueState(AOSContextManager::STATE_TERMINATE, &pContext); } } } } //a_Sleep between selects, requests in this queue are already slow AThread::sleep(pOwner->m_LoopDelay); } else AThread::sleep(pOwner->m_EmptyQueueDelay); //a_Nothing in queue, deep sleep } catch(AException& e) { pOwner->m_Services.useLog().addException(e); } catch(std::exception& e) { pOwner->m_Services.useLog().addException(e); } catch(...) { pOwner->m_Services.useLog().add(ASWNL("Unknown exception caught in AOSContextQueue_IsAvailable::threadproc"), ALog::EVENT_EXCEPTION); } } thread.setRunning(false); return 0; }