DWORD CNdasAutoRegister::ThreadStart(HANDLE hStopEvent) { CCoInitialize coinit(COINIT_MULTITHREADED); XTLASSERT(!m_hSemQueue.IsInvalid() && "Don't forget to call initialize()."); // Queue Semaphore, Terminating Thread, Pipe Instances(MAX...) HANDLE hWaitHandles[2] = { hStopEvent, m_hSemQueue }; CNdasDeviceHeartbeatListener& listener = pGetNdasDeviceHeartbeatListener(); COMVERIFY(listener.Advise(this)); do { DWORD waitResult = ::WaitForMultipleObjects( RTL_NUMBER_OF(hWaitHandles), hWaitHandles, FALSE, INFINITE); if (WAIT_OBJECT_0 == waitResult) { break; } else if (WAIT_OBJECT_0 + 1 == waitResult) { while (TRUE) { m_queueLock.LockInstance(); if (m_queue.empty()) { m_queueLock.UnlockInstance(); break; } QUEUE_ENTRY entry = m_queue.front(); m_queue.pop(); m_queueLock.UnlockInstance(); (VOID) ProcessRegister(entry.deviceID, entry.access); } } else { XTLASSERT(FALSE); // ERROR } } while (TRUE); COMVERIFY(listener.Unadvise(this)); return 0; }
DWORD CNdasDeviceHeartbeatListener::ThreadStart(HANDLE hStopEvent) { CCoInitialize coinit(COINIT_MULTITHREADED); DWORD ret; XTLTRACE2(NDASSVC_HEARTBEAT, TRACE_LEVEL_INFORMATION, "Starting NDAS Heartbeat Listener.\n"); CLpxDatagramServer dgramServer; BOOL success = dgramServer.Initialize(); if (!success) { XTLTRACE2(NDASSVC_HEARTBEAT, TRACE_LEVEL_ERROR, "CLpxDatagramServer init failed, error=0x%X\n", GetLastError()); return ret = 254; } success = dgramServer.Receive( this, m_ListenPort, sizeof(HEARTBEAT_RAW_DATA), hStopEvent); if (!success) { XTLTRACE2(NDASSVC_HEARTBEAT, TRACE_LEVEL_ERROR, "Listening Heartbeat at port %d failed, error=0x%X\n", m_ListenPort, GetLastError()); return ret = 255; } XTLTRACE2(NDASSVC_HEARTBEAT, TRACE_LEVEL_INFORMATION, "NDAS Heartbeat Stopped.\n"); return ret = 0; }
DWORD CNdasEventMonitor::ThreadStart(HANDLE hStopEvent) { CCoInitialize coinit(COINIT_MULTITHREADED); // 15 sec = 10,000,000 nanosec // negative value means relative time LARGE_INTEGER liDueTime; liDueTime.QuadPart = - 10 * 1000 * 1000; BOOL success = ::SetWaitableTimer( m_HeartbeatMonitorTimer, &liDueTime, HEARTBEAT_MONITOR_INTERVAL, NULL, NULL, FALSE); if (!success) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Setting waitable timer failed, error=0x%X\n", GetLastError()); } XTLVERIFY( ::ResetEvent(m_NdasLogicalUnitSetChanged) ); std::vector<HANDLE> waitHandles; waitHandles.reserve(20); // Lock-free copy of the devices and logDevices CInterfaceArray<INdasDevice> ndasDevices; CInterfaceArray<INdasLogicalUnit> ndasLogicalUnits; while (true) { // // Copy m_NdasDevices and m_NdasLogicalUnits to devices and logDevices // for lock free accesses // // DEVICE READER LOCK REGION { XTL::CReaderLockHolder holder(m_NdasDeviceDataLock); ndasDevices.Copy(m_NdasDevices); } { XTL::CReaderLockHolder holder(m_NdasLogicalUnitDataLock); ndasLogicalUnits.Copy(m_NdasLogicalUnits); } // DEVICE READER LOCK REGION // // Recreate wait handles // size_t ndasLogicalUnitCount = ndasLogicalUnits.GetCount(); waitHandles.resize(3 + ndasLogicalUnitCount * 2); waitHandles[0] = hStopEvent; waitHandles[1] = m_NdasLogicalUnitSetChanged; waitHandles[2] = m_HeartbeatMonitorTimer; // Disconnect events i=[3 ...3+nLogDevices) // Alarm Events events i=[3+nLogDevices ... 3+2*nLogDevices) for (size_t index = 0; index < ndasLogicalUnitCount; ++index) { INdasLogicalUnit* pNdasLogicalUnit = ndasLogicalUnits.GetAt(index); waitHandles[3 + index] = NdasLogicalUnitDisconnectEvent()(pNdasLogicalUnit); waitHandles[3 + index + ndasLogicalUnitCount] = NdasLogicalUnitAlarmEvent()(pNdasLogicalUnit); } DWORD nWaitHandles = waitHandles.size(); DWORD waitResult = ::WaitForMultipleObjects( nWaitHandles, &waitHandles[0], FALSE, INFINITE); if (WAIT_OBJECT_0 == waitResult) { // Terminate Thread Event XTLVERIFY( ::CancelWaitableTimer(m_HeartbeatMonitorTimer) ); return 0; } else if (WAIT_OBJECT_0 + 1 == waitResult) { // Logical device set change event XTLVERIFY( ::ResetEvent(m_NdasLogicalUnitSetChanged) ); continue; } else if (WAIT_OBJECT_0 + 2 == waitResult) { // Heartbeat Monitor Timer Event AtlForEach(ndasDevices, InvokeTimerEventSink<INdasDevice>()); AtlForEach(ndasLogicalUnits, InvokeTimerEventSink<INdasLogicalUnit>()); } else if ( waitResult >= WAIT_OBJECT_0 + 3 && waitResult < WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount) { XTLVERIFY( ::ResetEvent(waitHandles[waitResult - WAIT_OBJECT_0]) ); // Disconnect Event DWORD n = waitResult - (WAIT_OBJECT_0 + 3); OnLogicalDeviceDisconnected(ndasLogicalUnits[n]); } else if ( waitResult >= WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount && waitResult < WAIT_OBJECT_0 + 3 + 2 * ndasLogicalUnitCount) { XTLVERIFY( ::ResetEvent(waitHandles[waitResult - WAIT_OBJECT_0]) ); // Alarm Event DWORD n = waitResult - (WAIT_OBJECT_0 + 3 + ndasLogicalUnitCount); OnLogicalDeviceAlarmed(ndasLogicalUnits[n]); } else { XTLASSERT(FALSE); } } }
DWORD CNdasCommandServer::ThreadStart(LPVOID lpParam) { CCoInitialize coinit(COINIT_MULTITHREADED); HANDLE hStopEvent = static_cast<HANDLE>(lpParam); CmdWorkItemVector workItems; workItems.reserve(MaxPipeInstances); size_t size = workItems.size(); XTLASSERT(0 == size); std::generate_n( std::back_inserter(workItems), MaxPipeInstances, pWorkItemPtrGenerator); size = workItems.size(); XTLASSERT(MaxPipeInstances == size); DWORD nWorkItems = 0; for (DWORD i = 0; i < MaxPipeInstances; ++i) { CmdWorkItemPtr p = workItems[i]; BOOL success = p->QueueUserWorkItemEx( this, &CNdasCommandServer::CommandProcessStart, hStopEvent, WT_EXECUTELONGFUNCTION); if (success) { ++nWorkItems; } else { XTLTRACE2(NDASSVC_CMDSERVER, TRACE_LEVEL_ERROR, "Starting work item (%d/%d) failed, error=0x%X\n", i + 1, MaxPipeInstances, GetLastError()); } } // Release semaphore to start workers (semaphore increment) LONG prev; XTLVERIFY( ::ReleaseSemaphore(m_hProcSemaphore, nWorkItems, &prev) ); XTLASSERT( 0 == prev ); // Wait for stop event XTLVERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(hStopEvent, INFINITE)); // Stopped and waits for user work items DWORD finished = 0; while (finished < nWorkItems) { ::Sleep(0); DWORD waitResult = ::WaitForSingleObject(m_hProcSemaphore, 0); if (waitResult == WAIT_OBJECT_0) { XTLTRACE2(NDASSVC_CMDSERVER, TRACE_LEVEL_INFORMATION, "Command Process work item finished (%d/%d).\n", finished + 1, nWorkItems); ++finished; } XTLVERIFY(WAIT_OBJECT_0 == waitResult || WAIT_TIMEOUT == waitResult); } // Now Finally this thread can stop return 0; }
extern void cookie_analysis_init(){ coinit(); register_job(JOB_TYPE_COOKIES,process_function,process_judege,CALL_BY_TCP_DATA_MANAGE); }