mkernel 0.0.1
Micro-kernel framework, everything as a module
svcmgr.c
Go to the documentation of this file.
1
22#include "svcmgr.h"
23#include "gettext.h"
24#define _(String) gettext (String)
25
26#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
27#include <stdint.h>
28#include <string.h>
29#include <stdlib.h> /* free */
30#include <stdio.h> /* printf */
31
32#include "debug/assert.h"
33#include "debug/memory.h"
34
35typedef struct service_s {
36 struct service_s *next;
38 uint8_t nbArgs;
39 char *name;
42
44static service_t* services=NULL;
45
52static service_t* svcmgr_find(service_t* p_list, const char* p_name)
53{
54 int l_cmp; /*< string comparison */
55
56 ASSERT(p_name);
57 DBG_PRINTF("p_list=%p, p_name=%s",p_list,p_name);
58
59
60 l_cmp=0;
61 /* Search for the service name in the service list */
62 while ((p_list!=NULL)&&((l_cmp=strcmp(p_list->name,p_name))<0)) {
63 DBG_PRINTF("p_list=%p, p_list->next=%p",p_list,p_list->next);
64 DBG_PRINTF("p_list=%p, p_list->name=%s",p_list,p_list->name);
65 DBG_PRINTF("p_list=%p, l_cmp=%d",p_list,l_cmp);
66 if (l_cmp!=0)
67 p_list = p_list->next;
68 }
69
70 return (l_cmp==0?p_list:NULL);
71}
72
83static service_t* svcmgr_insert(service_t** p_list, service_t* p_service)
84{
85 int l_cmp; /*< string comparison */
86
87 ASSERT(p_list);
88 ASSERT(p_service);
89 DBG_PRINTF("p_list=%p, p_service=%p",p_list,p_service);
90
91 l_cmp=0;
92
93 /* Search for the service name in the service list */
94 while ((*p_list)&&((l_cmp=strcmp((*p_list)->name,p_service->name))<0))
95 p_list = &(*p_list)->next;
96
97 if ((*p_list==NULL)||(l_cmp>0)) {
99 p_service->next = *p_list;
100 *p_list = p_service;
101 /* End of critical section */
102 }
103
104 return *p_list;
105}
106
111static void svcmgr_rdelete(service_t* p_service)
112{
113 service_t* l_svc;
114
115 ASSERT(p_service);
116 DBG_PRINTF("p_service=%p",p_service);
117
118 l_svc = NULL;
119
120 /* Delete childrens */
121 while (p_service->children) {
122 l_svc = p_service->children;
123 p_service->children = p_service->next;
124 svcmgr_rdelete(l_svc);
125 }
126 /* Delete name */
127 free(p_service->name);
128 /* Delete record */
129 free(p_service);
130}
131
141static service_t* svcmgr_delete(service_t** p_list, const char* p_name)
142{
143 int l_cmp; /*< string comparison */
144
145 ASSERT(p_list);
146 ASSERT(p_name);
147 DBG_PRINTF("p_list=%p, p_name=%s",p_list,p_name);
148
149 l_cmp=0;
150
151 /* Search for the service name in the service list */
152 while ((*p_list)&&((l_cmp=strcmp((*p_list)->name,p_name))<0))
153 p_list = &(*p_list)->next;
154
155 if ((*p_list!=NULL)&&(l_cmp==0)) {
156 service_t* l_svc = *p_list;
157 *p_list = (*p_list)->next;
158 svcmgr_rdelete(l_svc);
159 }
160 return *p_list;
161}
162
163void svcmgr_dump(const char* p_prefix, service_t* p_list)
164{
165#ifndef NDEBUG
166 while (p_list) {
167 printf("%s%s\n",p_prefix, p_list->name);
168 if (p_list->children) {
169 char l_fullname[256];
170 snprintf(l_fullname,255,"%s%s/",p_prefix,p_list->name);
171 svcmgr_dump(l_fullname,p_list->children);
172 }
173 p_list = p_list->next;
174 }
175#else
176 /* Avoid unused parameters compilation warning for release builds */
177 ((void)p_prefix);
178 ((void)p_list);
179#endif
180}
181
182void svcmgr_register(const char* p_endpoint, svcfunc_t* p_svcfunc)
183{
184 char* l_token;
185 char* l_endpoint; /* Get rid of const qualifier */
186 service_t** l_head;
187 service_t* l_svc;
188 service_t* l_retsvc;
189
190 ASSERT(p_endpoint);
191 ASSERT(p_svcfunc);
192 DBG_PRINTF("p_endpoint=%s, p_svcfunc=%p",p_endpoint,p_svcfunc);
193
194 l_endpoint = strdup(p_endpoint);
195 DBG_PRINTF("l_endpoint=%s",l_endpoint);
196 l_head=&services;
197 DBG_PRINTF("l_head=%p, *l_head=%p",l_head,*l_head);
198 l_svc=NULL;
199 l_retsvc=NULL;
200
201 while ((l_token = strtok_r(l_endpoint,"/",&l_endpoint))) {
202 DBG_PRINTF("l_token=%s",l_token);
203 DBG_PRINTF("l_svc=%p",l_svc);
204 l_svc = (service_t*)malloc(sizeof(service_t));
205 DBG_PRINTF("l_svc=%p",l_svc);
206 l_svc->next=NULL;
207 l_svc->children=NULL;
208 l_svc->name=strdup(l_token);
209 if (strlen(l_endpoint)) {
210 /* Create a intermediate node */
211 l_svc->nbArgs=0;
212 l_svc->function=NULL;
213 } else {
214 /* Create an endpoint */
215 l_svc->nbArgs=0;
216 l_svc->function=p_svcfunc;
217 }
218 DBG_MSG("---------");
219 DBG_PRINTF("l_svc=%p",l_svc);
220 DBG_PRINTF("l_svc->next=%p",l_svc->next);
221 DBG_PRINTF("l_svc->children=%p",l_svc->children);
222 DBG_PRINTF("l_svc->nbArgs=%d",l_svc->nbArgs);
223 DBG_PRINTF("l_svc->name=%s",l_svc->name);
224 DBG_PRINTF("l_svc->function=%p",l_svc->function);
225 DBG_MSG("---------");
226 if (l_svc!=(l_retsvc=svcmgr_insert(l_head, l_svc)))
227 free(l_svc);
228 DBG_PRINTF("l_retsvc=%p",l_retsvc);
229 l_head=&(l_retsvc->children);
230 DBG_PRINTF("l_head=%p, *l_head=%p",l_head,*l_head);
231 };
232 svcmgr_dump("/",services);
233}
234
235uint8_t svcmgr_call(const char* p_endpoint,...)
236{
237 service_t* l_svc;
238
239 ASSERT(p_endpoint);
240 DBG_PRINTF("p_endpoint=%s",p_endpoint);
241
242 l_svc=svcmgr_find(services, p_endpoint);
243 DBG_PRINTF("l_svc=%p",l_svc);
244
245 if (l_svc) {
246 DBG_PRINTF("l_svc->function=%p",l_svc->function);
247 if (l_svc->function) {
248 va_list l_ap;
249 va_start(l_ap, p_endpoint);
250 l_svc->function(l_ap);
251 va_end(l_ap);
252 }
253 }
254
255 DBG_TRACE;
256 return 0;
257}
258
259void svcmgr_unregister(const char* p_endpoint)
260{
261 svcmgr_delete(&services, p_endpoint);
262}
263
264/*
265sem_init
266sem_wait
267sem_post
268sem_destroy
269sem_overview
270
271
272int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
273int pthread_mutex_lock(pthread_mutex_t *mutex);
274int pthread_mutex_unlock(pthread_mutex_t *mutex);
275int pthread_mutex_destroy(pthread_mutex_t *mutex);
276*/
Debugging macros.
#define DBG_TRACE
Checkpoint on stderr.
Definition: assert.h:118
#define DBG_PRINTF(p_Format,...)
Log a timestamped debugging message on stderr.
Definition: assert.h:155
#define ASSERT(condition)
Assertion check macro.
Definition: assert.h:103
#define DBG_MSG(msg)
Checkpoint on stderr with a static message.
Definition: assert.h:130
Tracks memory allocation and leaks when compiled without NDEBUG.
#define malloc(size)
Same syntaxt and same behavior than regular malloc function, with memory leaks tracking.
Definition: memory.h:32
#define strdup(chaine)
Same syntaxt and same behavior than regular strdup function, with memory leaks tracking.
Definition: memory.h:44
#define free(ptr)
Same syntaxt and same behavior than regular free function, with memory leaks tracking.
Definition: memory.h:41
#define NULL
Definition: mkernel-opt.c:64
char * name
Definition: svcmgr.c:39
struct service_s * children
Definition: svcmgr.c:37
struct service_s * next
Definition: svcmgr.c:36
svcfunc_t * function
Definition: svcmgr.c:40
uint8_t nbArgs
Definition: svcmgr.c:38
void svcmgr_dump(const char *p_prefix, service_t *p_list)
Definition: svcmgr.c:163
struct service_s service_t
void svcmgr_unregister(const char *p_endpoint)
Definition: svcmgr.c:259
void svcmgr_register(const char *p_endpoint, svcfunc_t *p_svcfunc)
Definition: svcmgr.c:182
uint8_t svcmgr_call(const char *p_endpoint,...)
Definition: svcmgr.c:235
Service manager header.
uint8_t svcfunc_t(va_list p_ap)
Definition: svcmgr.h:34