-
Notifications
You must be signed in to change notification settings - Fork 587
/
DHTModuleRegistry.c
111 lines (99 loc) · 3.76 KB
/
DHTModuleRegistry.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "dht/DHTModule.h"
#include "dht/DHTModuleRegistry.h"
#include "memory/Allocator.h"
#include "util/Assert.h"
#include <stddef.h> // NULL
#define DEBUG2(x, y)
/* #define DEBUG2(x, y) fprintf(stderr, x, y); fflush(stderr) */
struct DHTModuleRegistry* DHTModuleRegistry_new(struct Allocator* allocator, struct Log* log)
{
struct DHTModuleRegistry* reg =
Allocator_calloc(allocator, sizeof(struct DHTModuleRegistry), 1);
reg->allocator = allocator;
reg->members = Allocator_calloc(allocator, sizeof(char*), 1);
reg->log = log;
return reg;
}
int DHTModuleRegistry_register(struct DHTModule* module,
struct DHTModuleRegistry* registry)
{
registry->members = Allocator_realloc(registry->allocator,
registry->members,
sizeof(char*) * (registry->memberCount + 2));
registry->members[registry->memberCount] = module;
registry->memberCount++;
registry->members[registry->memberCount] = NULL;
return 0;
}
void DHTModuleRegistry_handleIncoming(struct DHTMessage* message,
const struct DHTModuleRegistry* registry)
{
if (!(message && registry && registry->members && registry->memberCount)) {
return;
}
struct DHTModule** firstModulePtr = registry->members;
struct DHTModule** modulePtr = registry->members + registry->memberCount - 1;
struct DHTModule* module;
while (modulePtr >= firstModulePtr) {
module = *modulePtr;
if (module && module->handleIncoming) {
DEBUG2("<< calling: %s->handleIncoming\n", module->name);
if (module->handleIncoming(message, module->context) != 0) {
// TODO(cjd): Call a debugger with all unhandlable messages?
return;
}
} else {
DEBUG2("<< skipping %s->handleIncoming\n", module->name);
}
modulePtr--;
}
}
static int dhtModuleHandleOutgoing(struct DHTModule* module, struct DHTMessage* message)
{
Assert_ifParanoid(module);
if (module->handleOutgoing) {
DEBUG2(">> calling: %s->handleOutgoing\n", module->name);
return module->handleOutgoing(message, module->context);
} else {
DEBUG2(">> skipping: %s->handleOutgoing\n", module->name);
}
return 0;
}
/**
* Do something to every module which is registered.
* @param doThis the callback.
* @param registry state.
*/
static void forEachModule(int (*doThis)(struct DHTModule* module, struct DHTMessage* message),
struct DHTMessage* message,
const struct DHTModuleRegistry* registry)
{
struct DHTModule** modulePtr = registry->members;
struct DHTModule* module = *modulePtr;
while (module) {
if (doThis(module, message) != 0) {
return;
}
modulePtr++;
module = *modulePtr;
}
}
void DHTModuleRegistry_handleOutgoing(struct DHTMessage* message,
const struct DHTModuleRegistry* registry)
{
forEachModule(dhtModuleHandleOutgoing, message, registry);
}