コード例 #1
0
STDMETHODIMP
CNdasLogicalUnitManager::get_NdasLogicalUnits(
	DWORD Flags, CInterfaceArray<INdasLogicalUnit>& dest)
{
	CAutoLock autolock(this);
	dest.Copy(m_NdasLogicalUnits);
	autolock.Release();

	if (NDAS_ENUM_EXCLUDE_HIDDEN & Flags)
	{
		//
		// Filter out hidden logical devices
		// A hidden logical device is a logical device, 
		// of which the device of the primary unit device
		// is hidden.
		//
		size_t count = dest.GetCount();
		for (size_t index = 0; index < count; ++index)
		{
			INdasLogicalUnit* p = dest.GetAt(index);
			if (NdasLogicalUnitIsHidden()(p))
			{
				dest.RemoveAt(index);
				--index; --count;
			}
		}
	}

	return S_OK;
}
コード例 #2
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);
		}
	}
}