2 Message handler database based on srvid
4 Copyright (C) Amitay Isaacs 2015
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
25 #include "lib/util/dlinklist.h"
26 #include "common/db_hash.h"
27 #include "common/srvid.h"
29 struct srvid_handler_list
;
31 struct srvid_context
{
32 struct db_hash_context
*dh
;
33 struct srvid_handler_list
*list
;
36 struct srvid_handler
{
37 struct srvid_handler
*prev
, *next
;
38 struct srvid_handler_list
*list
;
39 srvid_handler_fn handler
;
43 struct srvid_handler_list
{
44 struct srvid_handler_list
*prev
, *next
;
45 struct srvid_context
*srv
;
47 struct srvid_handler
*h
;
52 * Initialise message srvid context and database
54 int srvid_init(TALLOC_CTX
*mem_ctx
, struct srvid_context
**result
)
56 struct srvid_context
*srv
;
59 srv
= talloc_zero(mem_ctx
, struct srvid_context
);
64 ret
= db_hash_init(srv
, "messagedb", 8192, DB_HASH_SIMPLE
, &srv
->dh
);
75 * Wrapper functions to insert/delete/fetch srvid_hander_list
78 static int srvid_insert(struct srvid_context
*srv
, uint64_t srvid
,
79 struct srvid_handler_list
*list
)
81 return db_hash_insert(srv
->dh
, (uint8_t *)&srvid
, sizeof(uint64_t),
82 (uint8_t *)&list
, sizeof(list
));
85 static int srvid_delete(struct srvid_context
*srv
, uint64_t srvid
)
87 return db_hash_delete(srv
->dh
, (uint8_t *)&srvid
, sizeof(uint64_t));
90 static int srvid_fetch_parser(uint8_t *keybuf
, size_t keylen
,
91 uint8_t *databuf
, size_t datalen
,
94 struct srvid_handler_list
**list
=
95 (struct srvid_handler_list
**)private_data
;
97 if (datalen
!= sizeof(*list
)) {
101 *list
= *(struct srvid_handler_list
**)databuf
;
105 static int srvid_fetch(struct srvid_context
*srv
, uint64_t srvid
,
106 struct srvid_handler_list
**list
)
108 return db_hash_fetch(srv
->dh
, (uint8_t *)&srvid
, sizeof(uint64_t),
109 srvid_fetch_parser
, list
);
113 * When a handler is freed, remove it from the list
115 static int srvid_handler_destructor(struct srvid_handler
*h
)
117 struct srvid_handler_list
*list
= h
->list
;
119 DLIST_REMOVE(list
->h
, h
);
120 if (list
->h
== NULL
) {
127 * When a list is freed, remove all handlers and remove db entry
129 static int srvid_handler_list_destructor(struct srvid_handler_list
*list
)
131 struct srvid_handler
*h
;
133 while (list
->h
!= NULL
) {
135 DLIST_REMOVE(list
->h
, h
);
139 srvid_delete(list
->srv
, list
->srvid
);
140 DLIST_REMOVE(list
->srv
->list
, list
);
145 * Register a message handler
147 int srvid_register(struct srvid_context
*srv
, TALLOC_CTX
*mem_ctx
,
148 uint64_t srvid
, srvid_handler_fn handler
,
151 struct srvid_handler_list
*list
;
152 struct srvid_handler
*h
;
159 h
= talloc_zero(mem_ctx
, struct srvid_handler
);
164 h
->handler
= handler
;
165 h
->private_data
= private_data
;
167 ret
= srvid_fetch(srv
, srvid
, &list
);
169 /* srvid not yet registered */
170 list
= talloc_zero(srv
, struct srvid_handler_list
);
179 ret
= srvid_insert(srv
, srvid
, list
);
186 DLIST_ADD(srv
->list
, list
);
187 talloc_set_destructor(list
, srvid_handler_list_destructor
);
191 DLIST_ADD(list
->h
, h
);
192 talloc_set_destructor(h
, srvid_handler_destructor
);
197 * Deregister a message handler
199 int srvid_deregister(struct srvid_context
*srv
, uint64_t srvid
,
202 struct srvid_handler_list
*list
;
203 struct srvid_handler
*h
;
206 ret
= srvid_fetch(srv
, srvid
, &list
);
211 for (h
= list
->h
; h
!= NULL
; h
= h
->next
) {
212 if (h
->private_data
== private_data
) {
222 * Check if a message handler exists
224 int srvid_exists(struct srvid_context
*srv
, uint64_t srvid
)
226 struct srvid_handler_list
*list
;
229 ret
= srvid_fetch(srv
, srvid
, &list
);
233 if (list
->h
== NULL
) {
241 * Send a message to registered srvid and srvid_all
243 int srvid_dispatch(struct srvid_context
*srv
, uint64_t srvid
,
244 uint64_t srvid_all
, TDB_DATA data
)
246 struct srvid_handler_list
*list
;
247 struct srvid_handler
*h
;
250 ret
= srvid_fetch(srv
, srvid
, &list
);
252 for (h
= list
->h
; h
!= NULL
; h
= h
->next
) {
253 h
->handler(srvid
, data
, h
->private_data
);
257 if (srvid_all
== 0) {
261 ret
= srvid_fetch(srv
, srvid_all
, &list
);
263 for (h
= list
->h
; h
!= NULL
; h
= h
->next
) {
264 h
->handler(srvid
, data
, h
->private_data
);