ServiceManager.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "ServiceManager.h"
  2. #include "api__wasabi-replicant.h"
  3. #include "service/ifc_servicefactory.h"
  4. #include "service/svccb.h"
  5. using namespace nu;
  6. ServiceManager::ServiceManager()
  7. {
  8. #ifdef _WIN32
  9. component_wait = CreateSemaphoreW(NULL, 0, LONG_MAX, NULL);
  10. #else
  11. sem_init(&component_wait, 0, 0);
  12. #endif
  13. }
  14. ServiceManager::~ServiceManager()
  15. {
  16. #ifdef _WIN32
  17. if (component_wait)
  18. CloseHandle(component_wait);
  19. #else
  20. sem_destroy(&component_wait);
  21. #endif
  22. }
  23. int ServiceManager::Dispatchable_QueryInterface(GUID interface_guid, void **object)
  24. {
  25. if (interface_guid == ifc_component_sync::GetInterfaceGUID())
  26. {
  27. *object = (ifc_component_sync *)this;
  28. }
  29. return NErr_Unknown;
  30. }
  31. //-------------------------------------------
  32. int ServiceManager::GetServiceIndex(GUID key)
  33. {
  34. for(int idx = 0; idx < services_indexer.size(); idx++)
  35. {
  36. if (memcmp(&key, &services_indexer[idx], sizeof(GUID)) == 0)
  37. {
  38. return idx;
  39. }
  40. }
  41. return -1;
  42. }
  43. int ServiceManager::Service_Register(ifc_serviceFactory *svc)
  44. {
  45. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::service_register"));
  46. GUID service_type = svc->GetServiceType();
  47. GUID service_id = svc->GetGUID();
  48. // add the service to the master list
  49. ifc_serviceFactory* new_factory = services[service_id];
  50. if (new_factory) // if someone already has this GUID, we need to replace
  51. {
  52. // replace factory in services_by_type map
  53. ServiceList* type_list = services_by_type[service_type];
  54. if (type_list)
  55. {
  56. for (ServiceList::iterator itr=type_list->begin();itr!=type_list->end();itr++)
  57. {
  58. ifc_serviceFactory *f = *itr;
  59. if (f->GetGUID() == service_id)
  60. {
  61. *itr = svc;
  62. }
  63. }
  64. }
  65. // tell the old factory we're kicking its ass to the curb.
  66. new_factory->ServiceNotify(ifc_serviceFactory::ONUNREGISTERED);
  67. // HAKAN:
  68. // Should we delete old factory?
  69. // new_factory = svc;
  70. }
  71. else // not used yet, just assign
  72. {
  73. //new_factory = svc;
  74. services_indexer.push_back(service_id);
  75. // add it to the by-type lookup
  76. ServiceList *&type_list = services_by_type[service_type];
  77. if (!type_list)
  78. type_list = new ServiceList;
  79. type_list->push_back(svc);
  80. }
  81. services[service_id]=svc;
  82. // send notifications
  83. svc->ServiceNotify(ifc_serviceFactory::ONREGISTERED);
  84. WASABI2_API_SYSCB->IssueCallback(Service::event_type,
  85. Service::on_register,
  86. (intptr_t)&service_type, reinterpret_cast<intptr_t>(svc));
  87. return NErr_Success;
  88. }
  89. int ServiceManager::Service_Unregister(ifc_serviceFactory *svc)
  90. {
  91. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::Service_Unregister"));
  92. GUID service_type = svc->GetServiceType();
  93. GUID service_id = svc->GetGUID();
  94. // remove it from the master list
  95. ServiceMap::iterator itr = services.find(service_id);
  96. if (itr != services.end())
  97. services.erase(itr);
  98. // and from the type lookup map
  99. ServiceList *type_list = services_by_type[service_type];
  100. if (type_list)
  101. {
  102. //type_list->eraseObject(svc);
  103. for (auto it = type_list->begin(); it != type_list->end(); it++)
  104. {
  105. if (*it == svc)
  106. {
  107. it = type_list->erase(it);
  108. break;
  109. }
  110. }
  111. }
  112. WASABI2_API_SYSCB->IssueCallback(Service::event_type, Service::on_deregister, (intptr_t)&service_type, reinterpret_cast<intptr_t>(svc));
  113. svc->ServiceNotify(ifc_serviceFactory::ONUNREGISTERED);
  114. return NErr_Success;
  115. }
  116. size_t ServiceManager::Service_GetServiceCount(GUID svc_type)
  117. {
  118. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::Service_GetServiceCount"));
  119. ServiceList *type_list = services_by_type[svc_type];
  120. if (type_list)
  121. return type_list->size();
  122. else
  123. return 0;
  124. }
  125. ifc_serviceFactory *ServiceManager::Service_EnumService(GUID svc_type, size_t n)
  126. {
  127. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::Service_EnumService"));
  128. ServiceList *type_list = services_by_type[svc_type];
  129. if (type_list && (size_t)n < type_list->size())
  130. return type_list->at(n);
  131. else
  132. return 0;
  133. }
  134. ifc_serviceFactory *ServiceManager::Service_EnumService(size_t n)
  135. {
  136. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::Service_EnumService"));
  137. if ((size_t)n < services.size())
  138. {
  139. //return services.at(n).second;
  140. if (n < services_indexer.size())
  141. {
  142. GUID g = services_indexer[n];
  143. return services[g];
  144. }
  145. }
  146. return 0;
  147. }
  148. ifc_serviceFactory *ServiceManager::Service_GetServiceByGUID(GUID guid)
  149. {
  150. AutoLock lock(serviceGuard LOCKNAME("ServiceManager::service_getServiceByGuid"));
  151. ServiceMap::iterator itr = services.find(guid);
  152. if (itr != services.end())
  153. return itr->second;
  154. else
  155. return 0;
  156. }
  157. void ServiceManager::Service_ComponentDone()
  158. {
  159. #ifdef _WIN32
  160. ReleaseSemaphore(component_wait, 1, NULL);
  161. #else
  162. sem_post(&component_wait);
  163. #endif
  164. }
  165. int ServiceManager::ComponentSync_Wait(size_t count)
  166. {
  167. while (count--)
  168. {
  169. #ifdef _WIN32
  170. WaitForSingleObject(component_wait, INFINITE);
  171. #else
  172. sem_wait(&component_wait);
  173. #endif
  174. }
  175. return NErr_Success;
  176. }