123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- #include <precomp.h>
- #ifndef NOSVCMGR
- #include "svcmgr.h"
- #ifdef WASABI_COMPILE_COMPONENTS
- #include <api/wac/wac.h>
- #include <api/wac/compon.h>
- #endif
- #ifdef WASABI_COMPILE_SYSCB
- #include <api/syscb/cbmgr.h>
- #include <api/syscb/callbacks/syscb.h>
- #include <api/syscb/callbacks/svccb.h>
- #endif
- #include <bfc/multimap.h>
- #include <bfc/map.h>
- #include <bfc/critsec.h>
- static MultiMap<FOURCC, waServiceFactory> services;// list of factories by class
- static Map<waServiceFactory*, GUID> ownermap; // who presented it
- static Map<GUID, waServiceFactory*> services_by_guid;// unique services
- static Map<void *, waServiceFactory*> lockmap; // who to tell when it's unlocked
- //CUTstatic Map<void *, GUID> clientmap; // who locked it
- static CriticalSection cs;
- int ServiceManager::registerService(waServiceFactory *service, GUID owner) {
- ASSERT(owner != INVALID_GUID);
- if (owner == INVALID_GUID) return 0;
- FOURCC svctype = service->getServiceType();
- cs.enter();
- if (!services.multiHaveItem(svctype, service)) {
- services.multiAddItem(svctype, service);
- ownermap.addItem(service, owner);
- GUID svcguid = service->getGuid();
- if (svcguid != INVALID_GUID) services_by_guid.addItem(svcguid, service);
- }
- cs.leave();
- service->serviceNotify(SvcNotify::ONREGISTERED);
- #ifdef WASABI_COMPILE_SYSCB
- CallbackManager::issueCallback(SysCallback::SERVICE,
- SvcCallback::ONREGISTER,
- (int)svctype, reinterpret_cast<int>(service));
- #endif
- return 1;
- }
- int ServiceManager::deregisterService(waServiceFactory *service, int internal) {
- FOURCC svctype = service->getServiceType();
- // make sure it was there
- cs.enter();
- if (services.multiHaveItem(svctype, service)) {
- // make sure there aren't still services issued by this guy
- // ASSERT(internal || !lockmap.reverseGetItem(service));
- services.multiDelItem(svctype, service);
- ownermap.delItem(service);
- services_by_guid.reverseDelItem(service);
- }
- cs.leave();
- service->serviceNotify(SvcNotify::ONDEREGISTERED);
- #ifdef WASABI_COMPILE_SYSCB
- CallbackManager::issueCallback(SysCallback::SERVICE,
- SvcCallback::ONDEREGISTER,
- (int)svctype, reinterpret_cast<int>(service));
- #endif
- return 1;
- }
- int ServiceManager::getNumServices(FOURCC svc_type) {
- INCRITICALSECTION(cs);
- return services.multiGetNumItems(svc_type);
- }
- int ServiceManager::getNumServices() {
- return services.getNumItems();
- }
- waServiceFactory *ServiceManager::enumService(int n) {
- return services_by_guid.enumItemByPos(n, NULL);
- }
- int ServiceManager::getNumOwners() {
- return ownermap.getNumItems();
- }
- int ServiceManager::getNumServicesByGuid() {
- return services_by_guid.getNumItems();
- }
- int ServiceManager::getNumLocks() {
- return lockmap.getNumItems();
- }
- waServiceFactory *ServiceManager::enumService(FOURCC svc_type, int n) {
- INCRITICALSECTION(cs);
- waServiceFactory *ret = NULL;
- services.multiGetItem(svc_type, n, &ret);
- return ret;
- }
- waServiceFactory *ServiceManager::getServiceByGuid(GUID guid) {
- INCRITICALSECTION(cs);
- if (guid == INVALID_GUID) return NULL;
- waServiceFactory *ret=NULL;
- services_by_guid.getItem(guid, &ret);
- return ret;
- }
- void ServiceManager::sendNotification(int msg, int param1, int param2) {
- cs.enter();
- for (int x = 0; x < services.multiGetNumPairs(); x++) {
- for (int y = 0; ; y++) {
- waServiceFactory *svc;
- if (!services.multiGetItemDirect(x, y, &svc)) {
- break;
- }
- svc->serviceNotify(msg, param1, param2);
- }
- }
- cs.leave();
- #ifdef WASABI_COMPILE_COMPONENTS
- // also notify components
- for (int i = 0; ; i++) {
- WaComponent *wac = ComponentManager::enumComponent(i);
- if (wac == NULL) break;
- wac->onNotify(WAC_NOTIFY_SERVICE_NOTIFY, msg, param1, param2);
- }
- #endif
- #ifdef WASABI_COMPILE_SYSCB
- // and syscallbacks
- CallbackManager::issueCallback(SysCallback::RUNLEVEL, msg);
- #endif
- }
- int ServiceManager::lock(waServiceFactory *owner, void *svcptr) {
- INCRITICALSECTION(cs);
- if (owner == NULL || svcptr == NULL) return 0;
- // we allow multiple entries for same service
- lockmap.addItem(svcptr, owner);
- return 1;
- }
- int ServiceManager::unlock(void *svcptr) {
- if (svcptr == NULL) return 0;
- waServiceFactory *wsvc = NULL;
- cs.enter();
- if (!lockmap.getItem(svcptr, &wsvc)) {
- cs.leave();
- DebugString("WARNING: got unlock with no lock record!");
- return 0;
- }
- int r = lockmap.delItem(svcptr);
- ASSERT(r);
- //CUT // this might fail, client locking isn't enforceable
- //CUT clientmap.delItem(svcptr);
- cs.leave();
- return 1;
- }
- int ServiceManager::clientLock(void *svcptr, GUID lockedby) {
- //CUT INCRITICALSECTION(cs);
- //CUT ASSERT(svcptr != NULL);
- //CUT if (svcptr == NULL) return 0;
- //CUT ASSERT(lockedby != INVALID_GUID);
- //CUT if (lockedby == INVALID_GUID) return 0;
- //CUT clientmap.addItem(svcptr, lockedby);
- return 1;
- }
- int ServiceManager::release(void *svcptr) {
- if (svcptr == NULL) return 0;
- waServiceFactory *wsvc = NULL;
- cs.enter(); // note cs getting locked twice via release+unlock
- if (!lockmap.getItem(svcptr, &wsvc)) {
- cs.leave();
- DebugString("WARNING: got release with no lock record!");
- return 0;
- }
- unlock(svcptr);
- cs.leave();
-
- ASSERT(wsvc != NULL);
- return wsvc->releaseInterface(svcptr);
- }
- #ifdef WASABI_COMPILE_COMPONENTS
- GUID ServiceManager::getOwningComponent(void *svcptr) {
- INCRITICALSECTION(cs);
- GUID ret = INVALID_GUID;
- waServiceFactory *svc=NULL;
- if (lockmap.getItem(svcptr, &svc)) ownermap.getItem(svc, &ret);
- return ret;
- }
- GUID ServiceManager::getLockingComponent(void *svcptr) {
- INCRITICALSECTION(cs);
- GUID ret = INVALID_GUID;
- //CUT clientmap.getItem(svcptr, &ret);
- return ret;
- }
- #endif
- using namespace WaSvc;
- static struct {
- FOURCC type;
- const char *name;
- } svc_names[] = {
- { DEVICE, "Portable Device" },
- { FILEREADER, "File Reader" },
- { FILESELECTOR, "File Selector" },
- { IMAGEGENERATOR, "Image Generator" },
- { IMAGELOADER, "Image Loader" },
- { ITEMMANAGER, "Item Manager" },
- { MEDIACONVERTER, "Media Converter" },
- { MEDIACORE, "Media Core" },
- { PLAYLISTREADER, "Playlist Reader" },
- { PLAYLISTWRITER, "Playlist Writer" },
- { SCRIPTOBJECT, "Script Class" },
- { XMLPROVIDER, "XML Provider" },
- { DB, "Database" },
- { EVALUATOR, "Evaluator" },
- { COREADMIN, "Core Administrator" },
- { NONE, NULL }, // this one has to be last
- };
- const char *ServiceManager::getServiceTypeName(FOURCC svc_type) {
- for (int i = 0; ; i++) {
- if (svc_names[i].name == NULL) break;
- if (svc_names[i].type == svc_type) return svc_names[i].name;
- }
- return NULL;
- }
- FOURCC ServiceManager::safe_getServiceType(waServiceFactory *was) {
- #ifndef _DEBUG
- return 0;
- #endif
- FOURCC type = 0;
- _TRY
- {
- type = was->getServiceType();
- }
- _EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- OutputDebugString("EXCEPTION_EXECUTE_HANDLER\n");
- }
- return type;
- }
- const char *ServiceManager::safe_getServiceName(waServiceFactory *was) {
- #ifndef _DEBUG
- return 0;
- #endif
- const char *name = NULL;
- _TRY
- {
- name = was->getServiceName();
- }
- _EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- OutputDebugString("EXCEPTION_EXECUTE_HANDLER\n");
- }
- return name;
- }
- void ServiceManager::onShutdown() {
- /*
- ownermap.purge();
- services.purge();
- services_by_guid.purge();
- clientmap.purge();
- */
- int nlocks = lockmap.getNumPairs();
- if (nlocks <= 0) {
- //lockmap.purge();
- #ifdef GEN_FF // i need this to have clean session restart, feel free to remove the ifdef if you fgeel that should always be done
- ownermap.deleteAll();
- services.multiRemoveAll();
- services_by_guid.deleteAll();
- lockmap.deleteAll();
- #endif
- return;
- }
- #ifndef _DEBUG
- DebugString("-----------------\n");
- for (int i = 0; i < nlocks; i++) {
- void *ptr = lockmap.enumIndexByPos(i, NULL); ASSERT(ptr != NULL);
- StringPrintf s("lock: %d type:'", (int)ptr);
- // GUID g = lockermap.enumItemByPos(i, INVALID_GUID);ASSERT(g != INVALID_GUID);
- // s += g;
- // WaComponent *wac = ComponentManager::getComponentFromGuid(g);
- waServiceFactory *was=NULL;
- was = lockmap.enumItemByPos(i, NULL);
- ASSERT(was != NULL);
- FOURCC type = safe_getServiceType(was);
- const char *tname = ServiceManager::getServiceTypeName(type);
- if (tname != NULL) {
- s += tname;
- } else {
- FOURCC v = BSWAP(type);
- unsigned char bleh[5]=" ";
- MEMCPY(bleh, &v, 4);
- s += String((char *)bleh);
- }
- s += "' from service:'";
- s += safe_getServiceName(was);
- // s += " wac:";
- // if (wac) s += wac->getName();
- #ifdef WASABI_COMPILE_COMPONENTS
- s += "' owned by:'";
- GUID g = INVALID_GUID;
- ownermap.getItem(was, &g);
- if (g != INVALID_GUID) {
- s += g;
- WaComponent *wac = ComponentManager::getComponentFromGuid(g);
- if (wac) s += wac->getName();
- } else s += "(unregistered)";
- #else
- GUID g;
- #endif
- s += "' registered lock to '";
- g = INVALID_GUID;
- //clientmap.getItem(ptr, &g);
- s += g;
- s += "'\n";
- DebugString(s.v());
- }
- DebugString("-----------------\n");
- #endif
- #ifdef GEN_FF // i need this to have clean session restart, feel free to remove the ifdef if you fgeel that should always be done
- ownermap.deleteAll();
- services.multiRemoveAll();
- services_by_guid.deleteAll();
- lockmap.deleteAll();
- #endif
- }
- int ServiceManager::isValidService(FOURCC svctype, waServiceFactory *service) {
- INCRITICALSECTION(cs);
- return services.multiHaveItem(svctype, service);
- }
- #endif
|