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;
}
Beispiel #5
0
extern void cookie_analysis_init(){
    coinit();
    register_job(JOB_TYPE_COOKIES,process_function,process_judege,CALL_BY_TCP_DATA_MANAGE);
}