1 /* 2 * Copyright 2014, Rene Gollent, rene@gollent.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "ImageDebugLoadingStateHandlerRoster.h" 8 9 #include <new> 10 11 #include <AutoDeleter.h> 12 #include <AutoLocker.h> 13 14 #include "DwarfLoadingStateHandler.h" 15 #include "ImageDebugInfoLoadingState.h" 16 #include "ImageDebugLoadingStateHandler.h" 17 #include "SpecificImageDebugInfoLoadingState.h" 18 19 20 /*static*/ ImageDebugLoadingStateHandlerRoster* 21 ImageDebugLoadingStateHandlerRoster::sDefaultInstance = NULL; 22 23 24 ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster() 25 : 26 fLock("loading state handler roster"), 27 fStateHandlers(20, false) 28 { 29 } 30 31 32 ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster() 33 { 34 for (int32 i = 0; ImageDebugLoadingStateHandler* handler 35 = fStateHandlers.ItemAt(i); i++) { 36 handler->ReleaseReference(); 37 } 38 } 39 40 41 /*static*/ ImageDebugLoadingStateHandlerRoster* 42 ImageDebugLoadingStateHandlerRoster::Default() 43 { 44 return sDefaultInstance; 45 } 46 47 48 /*static*/ status_t 49 ImageDebugLoadingStateHandlerRoster::CreateDefault() 50 { 51 if (sDefaultInstance != NULL) 52 return B_OK; 53 54 ImageDebugLoadingStateHandlerRoster* roster 55 = new(std::nothrow) ImageDebugLoadingStateHandlerRoster; 56 if (roster == NULL) 57 return B_NO_MEMORY; 58 ObjectDeleter<ImageDebugLoadingStateHandlerRoster> rosterDeleter(roster); 59 60 status_t error = roster->Init(); 61 if (error != B_OK) 62 return error; 63 64 error = roster->RegisterDefaultHandlers(); 65 if (error != B_OK) 66 return error; 67 68 sDefaultInstance = rosterDeleter.Detach(); 69 return B_OK; 70 } 71 72 73 /*static*/ void 74 ImageDebugLoadingStateHandlerRoster::DeleteDefault() 75 { 76 ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance; 77 sDefaultInstance = NULL; 78 delete roster; 79 } 80 81 82 status_t 83 ImageDebugLoadingStateHandlerRoster::Init() 84 { 85 return fLock.InitCheck(); 86 } 87 88 89 status_t 90 ImageDebugLoadingStateHandlerRoster::RegisterDefaultHandlers() 91 { 92 ImageDebugLoadingStateHandler* handler; 93 BReference<ImageDebugLoadingStateHandler> handlerReference; 94 95 handler = new(std::nothrow) DwarfLoadingStateHandler(); 96 if (handler == NULL) 97 return B_NO_MEMORY; 98 handlerReference.SetTo(handler, true); 99 100 if (!RegisterHandler(handler)) 101 return B_NO_MEMORY; 102 103 return B_OK; 104 } 105 106 107 status_t 108 ImageDebugLoadingStateHandlerRoster::FindStateHandler( 109 SpecificImageDebugInfoLoadingState* state, 110 ImageDebugLoadingStateHandler*& _handler) 111 { 112 AutoLocker<BLocker> locker(fLock); 113 114 bool found = false; 115 ImageDebugLoadingStateHandler* handler = NULL; 116 for (int32 i = 0; (handler = fStateHandlers.ItemAt(i)); i++) { 117 if ((found = handler->SupportsState(state))) 118 break; 119 } 120 121 if (!found) 122 return B_ENTRY_NOT_FOUND; 123 124 handler->AcquireReference(); 125 _handler = handler; 126 return B_OK; 127 } 128 129 130 bool 131 ImageDebugLoadingStateHandlerRoster::RegisterHandler( 132 ImageDebugLoadingStateHandler* handler) 133 { 134 if (!fStateHandlers.AddItem(handler)) 135 return false; 136 137 handler->AcquireReference(); 138 return true; 139 } 140 141 142 void 143 ImageDebugLoadingStateHandlerRoster::UnregisterHandler( 144 ImageDebugLoadingStateHandler* handler) 145 { 146 if (fStateHandlers.RemoveItem(handler)) 147 handler->ReleaseReference(); 148 } 149