xref: /haiku/src/kits/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp (revision 2897df967633aab846ff4917b53e2af7d1e54eeb)
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