Line data Source code
1 : /*
2 : * libpino - handler.c
3 : *
4 : */
5 :
6 : #include <pino.h>
7 : #include <pino/handler.h>
8 :
9 : #include <pino_internal.h>
10 :
11 : static struct {
12 : bool initialized;
13 : size_t capacity;
14 : size_t usage;
15 : handler_entry_t **entries;
16 : } g_handlers;
17 :
18 6 : static inline bool glow_handlers(size_t step)
19 : {
20 : handler_entry_t **entries;
21 : size_t i;
22 :
23 6 : entries = (handler_entry_t **)prealloc(g_handlers.entries, (g_handlers.capacity + step) * sizeof(handler_entry_t *));
24 6 : if (!entries) {
25 : return false; /* LCOV_EXCL_LINE */
26 : }
27 :
28 1014 : for (i = g_handlers.capacity; i < g_handlers.capacity + step; i++) {
29 1008 : entries[i] = NULL;
30 : }
31 :
32 6 : g_handlers.entries = entries;
33 6 : g_handlers.capacity += step;
34 :
35 : PINO_SUPRTF("glowed capacity: %zu, usage: %zu", g_handlers.capacity, g_handlers.usage);
36 :
37 6 : return true;
38 : }
39 :
40 18 : extern bool pino_handler_init(size_t initialize_size)
41 : {
42 : handler_entry_t **ents;
43 : size_t i;
44 :
45 18 : if (g_handlers.initialized) {
46 : return true; /* LCOV_EXCL_LINE */
47 : }
48 :
49 18 : g_handlers.initialized = false;
50 18 : g_handlers.capacity = initialize_size;
51 18 : g_handlers.usage = 0;
52 :
53 18 : ents = (handler_entry_t **)pcalloc(initialize_size, sizeof(handler_entry_t *));
54 18 : if (!ents) {
55 : return false; /* LCOV_EXCL_LINE */
56 : }
57 :
58 162 : for (i = 0; i < initialize_size; i++) {
59 144 : ents[i] = NULL;
60 : }
61 :
62 18 : g_handlers.entries = ents;
63 :
64 : PINO_SUPRTF("usage: %zu, capacity: %zu", g_handlers.usage, g_handlers.capacity);
65 :
66 18 : return g_handlers.initialized = true;
67 : }
68 :
69 18 : extern void pino_handler_free(void)
70 : {
71 : size_t i, j;
72 :
73 18 : if (!g_handlers.initialized) {
74 : return; /* LCOV_EXCL_LINE */
75 : }
76 :
77 1170 : for (i = 0; i < g_handlers.capacity; i++) {
78 1152 : if (g_handlers.entries[i]) {
79 1004 : pino_memory_manager_obj_free(&g_handlers.entries[i]->mm);
80 1004 : pfree(g_handlers.entries[i]);
81 1004 : g_handlers.entries[i] = NULL;
82 1004 : --g_handlers.usage;
83 :
84 : PINO_SUPRTF("freeing: %zu, usage: %zu, capacity: %zu", i, g_handlers.usage, g_handlers.capacity);
85 : }
86 : }
87 :
88 18 : pfree(g_handlers.entries);
89 :
90 18 : g_handlers.initialized = false;
91 : }
92 :
93 1034 : extern bool pino_handler_register(pino_magic_safe_t magic, pino_handler_t *handler)
94 : {
95 : handler_entry_t *entry;
96 : size_t i;
97 :
98 1034 : if (!handler) {
99 : PINO_SUPRTF("handler is NULL");
100 1 : return false;
101 : }
102 :
103 1033 : if (!validate_magic(magic)) {
104 : PINO_SUPRTF("magic is invalid");
105 5 : return false;
106 : }
107 :
108 1028 : if (pino_handler_find(magic)) {
109 : PINO_SUPRTF("magic: %.4s already registered", magic);
110 2 : return false;
111 : }
112 :
113 1026 : if (g_handlers.usage >= g_handlers.capacity) {
114 6 : if (!glow_handlers(g_handlers.capacity + HANDLER_STEP)) {
115 : return false; /* LCOV_EXCL_LINE */
116 : }
117 : }
118 :
119 1026 : entry = (handler_entry_t *)pmalloc(sizeof(handler_entry_t));
120 1026 : if (!entry) {
121 : return false; /* LCOV_EXCL_LINE */
122 : }
123 :
124 1026 : if (!pino_memory_manager_obj_init(&entry->mm, MM_STEP)) {
125 : /* LCOV_EXCL_START */
126 : pfree(entry);
127 : PINO_SUPRTF("pino_memory_manager_obj_init failed");
128 : return false;
129 : /* LCOV_EXCL_STOP */
130 : }
131 :
132 1026 : pmemcpy(entry->magic, magic, sizeof(pino_magic_t));
133 1026 : entry->handler = handler;
134 1026 : handler->entry = entry;
135 :
136 501541 : for (i = 0; i < g_handlers.capacity; i++) {
137 501541 : if (!g_handlers.entries[i]) {
138 1026 : g_handlers.entries[i] = entry;
139 1026 : ++g_handlers.usage;
140 :
141 : PINO_SUPRTF("magic: %.4s, using: %zu, usage: %zu, capacity: %zu", magic, i, g_handlers.usage, g_handlers.capacity);
142 :
143 1026 : return true;
144 : }
145 : }
146 :
147 : /* LCOV_EXCL_START */
148 : PINO_SUPUNREACH();
149 : return false;
150 : /* LCOV_EXCL_STOP */
151 : }
152 :
153 23 : extern bool pino_handler_unregister(pino_magic_safe_t magic)
154 : {
155 : size_t i;
156 :
157 23 : if (!g_handlers.initialized) {
158 : return false; /* LCOV_EXCL_LINE */
159 : }
160 :
161 23 : if (!validate_magic(magic)) {
162 : PINO_SUPRTF("magic is invalid");
163 1 : return false;
164 : }
165 :
166 27 : for (i = 0; i < g_handlers.usage; i++) {
167 27 : if (g_handlers.entries[i] && magic_equal(g_handlers.entries[i]->magic, magic)) {
168 22 : pino_memory_manager_obj_free(&g_handlers.entries[i]->mm);
169 22 : pfree(g_handlers.entries[i]);
170 22 : g_handlers.entries[i] = NULL;
171 22 : --g_handlers.usage;
172 :
173 : PINO_SUPRTF("freeing: %zu, usage: %zu, capacity: %zu", i, g_handlers.usage, g_handlers.capacity);
174 :
175 22 : return true;
176 : }
177 : }
178 :
179 : /* LCOV_EXCL_START */
180 : PINO_SUPUNREACH();
181 : return false;
182 : /* LCOV_EXCL_STOP */
183 : }
184 :
185 2039 : extern pino_handler_t *pino_handler_find(pino_magic_safe_t magic)
186 : {
187 : size_t i;
188 :
189 2039 : if (!g_handlers.initialized) {
190 : return NULL; /* LCOV_EXCL_LINE */
191 : }
192 :
193 502561 : for (i = 0; i < g_handlers.usage; i++) {
194 501530 : if (g_handlers.entries[i] && magic_equal(g_handlers.entries[i]->magic, magic)) {
195 1008 : return g_handlers.entries[i]->handler;
196 : }
197 : }
198 :
199 : /* LCOV_EXCL_START */
200 : PINO_SUPRTF("magic: %.4s not found", magic);
201 : return NULL;
202 : /* LCOV_EXCL_STOP */
203 : }
|