1
0

deviceprovider.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include "P4SDevice.h"
  2. #include "./deviceprovider.h"
  3. #include "../devices/api_devicemanager.h"
  4. #include "../nu/threadpool/api_threadpool.h"
  5. void checkForDevices(BOOL *killSwitch);
  6. BOOL
  7. QueueThreadFunction(api_threadpool::ThreadPoolFunc func, void *user, intptr_t id);
  8. DeviceProvider::DeviceProvider()
  9. : ref(1), activity(0), manager(NULL), readyEvent(NULL), cancelDiscovery(FALSE)
  10. {
  11. InitializeCriticalSection(&lock);
  12. }
  13. DeviceProvider::~DeviceProvider()
  14. {
  15. CancelDiscovery();
  16. if (NULL != readyEvent)
  17. CloseHandle(readyEvent);
  18. DeleteCriticalSection(&lock);
  19. }
  20. HRESULT DeviceProvider::CreateInstance(DeviceProvider **instance)
  21. {
  22. if (NULL == instance)
  23. return E_POINTER;
  24. *instance = new DeviceProvider();
  25. if (NULL == *instance)
  26. return E_OUTOFMEMORY;
  27. return S_OK;
  28. }
  29. size_t DeviceProvider::AddRef()
  30. {
  31. return InterlockedIncrement((LONG*)&ref);
  32. }
  33. size_t DeviceProvider::Release()
  34. {
  35. if (0 == ref)
  36. return ref;
  37. LONG r = InterlockedDecrement((LONG*)&ref);
  38. if (0 == r)
  39. delete(this);
  40. return r;
  41. }
  42. int DeviceProvider::QueryInterface(GUID interface_guid, void **object)
  43. {
  44. if (NULL == object)
  45. return E_POINTER;
  46. if (IsEqualIID(interface_guid, IFC_DeviceProvider))
  47. *object = static_cast<ifc_deviceprovider*>(this);
  48. else
  49. {
  50. *object = NULL;
  51. return E_NOINTERFACE;
  52. }
  53. if (NULL == *object)
  54. return E_UNEXPECTED;
  55. AddRef();
  56. return S_OK;
  57. }
  58. void DeviceProvider::Lock()
  59. {
  60. EnterCriticalSection(&lock);
  61. }
  62. void DeviceProvider::Unlock()
  63. {
  64. LeaveCriticalSection(&lock);
  65. }
  66. DWORD DeviceProvider::DiscoveryThread()
  67. {
  68. IncrementActivity();
  69. if (FALSE == cancelDiscovery)
  70. {
  71. checkForDevices(&cancelDiscovery);
  72. }
  73. DecrementActivity();
  74. Lock();
  75. if (NULL != readyEvent)
  76. SetEvent(readyEvent);
  77. Unlock();
  78. return 0;
  79. }
  80. static int DeviceProvider_DiscoveryThreadStarter(HANDLE handle, void *user, intptr_t id)
  81. {
  82. DeviceProvider *self;
  83. DWORD result;
  84. self = (DeviceProvider*)user;
  85. if (NULL != self)
  86. result = self->DiscoveryThread();
  87. else
  88. result = -2;
  89. return result;
  90. }
  91. HRESULT DeviceProvider::BeginDiscovery(api_devicemanager *manager)
  92. {
  93. HRESULT hr;
  94. Lock();
  95. if (NULL != readyEvent &&
  96. WAIT_TIMEOUT == WaitForSingleObject(readyEvent, 0))
  97. {
  98. hr = E_PENDING;
  99. }
  100. else
  101. {
  102. hr = S_OK;
  103. if (NULL == readyEvent)
  104. {
  105. readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
  106. if (NULL == readyEvent)
  107. hr = E_FAIL;
  108. }
  109. if (SUCCEEDED(hr))
  110. {
  111. cancelDiscovery = FALSE;
  112. ResetEvent(readyEvent);
  113. if (FALSE == QueueThreadFunction(DeviceProvider_DiscoveryThreadStarter,
  114. this, 0))
  115. {
  116. SetEvent(readyEvent);
  117. hr = E_FAIL;
  118. }
  119. }
  120. }
  121. Unlock();
  122. return hr;
  123. }
  124. HRESULT DeviceProvider::CancelDiscovery()
  125. {
  126. HRESULT hr;
  127. hr = S_FALSE;
  128. Lock();
  129. if (NULL != readyEvent)
  130. {
  131. cancelDiscovery = TRUE;
  132. if (WAIT_OBJECT_0 == WaitForSingleObject(readyEvent, 0))
  133. hr = S_OK;
  134. cancelDiscovery = FALSE;
  135. }
  136. Unlock();
  137. return hr;
  138. }
  139. HRESULT DeviceProvider::GetActive()
  140. {
  141. HRESULT hr;
  142. Lock();
  143. if (0 != activity)
  144. hr = S_OK;
  145. else
  146. hr = S_FALSE;
  147. Unlock();
  148. return hr;
  149. }
  150. HRESULT DeviceProvider::Register(api_devicemanager *manager)
  151. {
  152. HRESULT hr;
  153. if (NULL != this->manager)
  154. return E_UNEXPECTED;
  155. if (NULL == manager)
  156. return E_POINTER;
  157. hr = manager->RegisterProvider(this);
  158. if (SUCCEEDED(hr))
  159. {
  160. this->manager = manager;
  161. manager->AddRef();
  162. }
  163. return hr;
  164. }
  165. HRESULT DeviceProvider::Unregister()
  166. {
  167. HRESULT hr;
  168. if (NULL == manager)
  169. return E_UNEXPECTED;
  170. hr = manager->UnregisterProvider(this);
  171. manager->Release();
  172. manager = NULL;
  173. return hr;
  174. }
  175. size_t DeviceProvider::IncrementActivity()
  176. {
  177. size_t a;
  178. Lock();
  179. activity++;
  180. if (1 == activity &&
  181. NULL != manager)
  182. {
  183. manager->SetProviderActive(this, TRUE);
  184. }
  185. a = activity;
  186. Unlock();
  187. return a;
  188. }
  189. size_t DeviceProvider::DecrementActivity()
  190. {
  191. size_t a;
  192. Lock();
  193. if (0 != activity)
  194. {
  195. activity--;
  196. if (0 == activity &&
  197. NULL != manager)
  198. {
  199. manager->SetProviderActive(this, FALSE);
  200. }
  201. }
  202. a = activity;
  203. Unlock();
  204. return a;
  205. }
  206. #define CBCLASS DeviceProvider
  207. START_DISPATCH;
  208. CB(ADDREF, AddRef)
  209. CB(RELEASE, Release)
  210. CB(QUERYINTERFACE, QueryInterface)
  211. CB(API_BEGINDISCOVERY, BeginDiscovery)
  212. CB(API_CANCELDISCOVERY, CancelDiscovery)
  213. CB(API_GETACTIVE, GetActive)
  214. END_DISPATCH;
  215. #undef CBCLASS