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 24ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster() 25 : 26 fLock("loading state handler roster"), 27 fStateHandlers(20, false) 28{ 29} 30 31 32ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster() 33{ 34 for (int32 i = 0; ImageDebugLoadingStateHandler* handler 35 = fStateHandlers.ItemAt(i); i++) { 36 handler->ReleaseReference(); 37 } 38} 39 40 41/*static*/ ImageDebugLoadingStateHandlerRoster* 42ImageDebugLoadingStateHandlerRoster::Default() 43{ 44 return sDefaultInstance; 45} 46 47 48/*static*/ status_t 49ImageDebugLoadingStateHandlerRoster::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 74ImageDebugLoadingStateHandlerRoster::DeleteDefault() 75{ 76 ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance; 77 sDefaultInstance = NULL; 78 delete roster; 79} 80 81 82status_t 83ImageDebugLoadingStateHandlerRoster::Init() 84{ 85 return fLock.InitCheck(); 86} 87 88 89status_t 90ImageDebugLoadingStateHandlerRoster::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 107status_t 108ImageDebugLoadingStateHandlerRoster::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 130bool 131ImageDebugLoadingStateHandlerRoster::RegisterHandler( 132 ImageDebugLoadingStateHandler* handler) 133{ 134 if (!fStateHandlers.AddItem(handler)) 135 return false; 136 137 handler->AcquireReference(); 138 return true; 139} 140 141 142void 143ImageDebugLoadingStateHandlerRoster::UnregisterHandler( 144 ImageDebugLoadingStateHandler* handler) 145{ 146 if (fStateHandlers.RemoveItem(handler)) 147 handler->ReleaseReference(); 148} 149