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