Skip to content

Commit 6e40897

Browse files
committed
cleanup(core,tests,samples): completely drop m_ctx_t param from context API.
Moreover, avoid forward declaring the struct and exposing it to the user. This enforces the law that context <-> thread, and users cannot escape this rule (eg: by passing around a context handler between threads). Signed-off-by: Federico Di Pierro <[email protected]>
1 parent 85089e0 commit 6e40897

File tree

28 files changed

+177
-284
lines changed

28 files changed

+177
-284
lines changed

Lib/core/ctx.c

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static int recv_events(m_ctx_t *c, int timeout);
2222
static int m_ctx_loop_events(m_ctx_t *c, int max_events);
2323
static int ctx_destroy_mods(void *data, const char *key, void *value);
2424
static ev_src_t *process_tick(ev_src_t *this, m_ctx_t *c, int idx, evt_priv_t *evt);
25-
static int ctx_new(const char *ctx_name, m_ctx_t **c, m_ctx_flags flags, const void *userdata);
25+
static int ctx_new(const char *ctx_name, m_ctx_flags flags, const void *userdata);
2626

2727
static void make_key(void) {
2828
pthread_key_create(&key, NULL);
@@ -119,7 +119,7 @@ static uint8_t loop_stop(m_ctx_t *c) {
119119
* Gracefully deregister it now.
120120
*/
121121
if (m_map_len(c->modules) == 0 && !(c->flags & M_CTX_PERSIST)) {
122-
m_ctx_deregister(&c);
122+
m_ctx_deregister();
123123
}
124124
return ret;
125125
}
@@ -317,7 +317,6 @@ static int recv_events(m_ctx_t *c, int timeout) {
317317
}
318318

319319
static int m_ctx_loop_events(m_ctx_t *c, int max_events) {
320-
M_CTX_ASSERT(c);
321320
M_PARAM_ASSERT(max_events > 0);
322321
M_LOG_ASSERT(c->state == M_CTX_IDLE, "Context already looping.", -EINVAL);
323322

@@ -342,7 +341,7 @@ static ev_src_t *process_tick(ev_src_t *this, m_ctx_t *c, int idx, evt_priv_t *e
342341
return this;
343342
}
344343

345-
static int ctx_new(const char *ctx_name, m_ctx_t **c, m_ctx_flags flags, const void *userdata) {
344+
static int ctx_new(const char *ctx_name, m_ctx_flags flags, const void *userdata) {
346345
M_DEBUG("Creating context '%s'.\n", ctx_name);
347346

348347
m_ctx_t *new_ctx = m_mem_new(sizeof(m_ctx_t), ctx_dtor);
@@ -377,17 +376,22 @@ static int ctx_new(const char *ctx_name, m_ctx_t **c, m_ctx_flags flags, const v
377376
ret = pthread_setspecific(key, new_ctx);
378377
} while (false);
379378

380-
if (ret == 0) {
381-
*c = new_ctx;
382-
} else {
383-
*c = NULL;
379+
if (ret != 0) {
384380
m_mem_unref(new_ctx);
385381
}
386382
return ret;
387383
}
388384

389385
/** Private API **/
390386

387+
m_ctx_t *m_ctx(void) {
388+
m_ctx_t *c = pthread_getspecific(key);
389+
if (c && c->curr_mod) {
390+
M_RET_ASSERT(!(c->curr_mod->flags & M_MOD_DENY_CTX), NULL);
391+
}
392+
return c;
393+
}
394+
391395
void inline ctx_logger(const m_ctx_t *c, const m_mod_t *mod, const char *fmt, ...) {
392396
va_list args;
393397
va_start(args, fmt);
@@ -397,69 +401,56 @@ void inline ctx_logger(const m_ctx_t *c, const m_mod_t *mod, const char *fmt, ..
397401

398402
/** Public API **/
399403

400-
_public_ m_ctx_t *m_ctx(void) {
401-
m_ctx_t *c = pthread_getspecific(key);
402-
if (c && c->curr_mod) {
403-
M_RET_ASSERT(!(c->curr_mod->flags & M_MOD_DENY_CTX), NULL);
404-
}
405-
return c;
406-
}
407-
408-
_public_ int m_ctx_register(const char *ctx_name, OUT m_ctx_t **c, m_ctx_flags flags, const void *userdata) {
404+
_public_ int m_ctx_register(const char *ctx_name, m_ctx_flags flags, const void *userdata) {
409405
M_PARAM_ASSERT(str_not_empty(ctx_name));
410-
M_PARAM_ASSERT(c);
411-
M_PARAM_ASSERT(!*c);
412406

413407
pthread_once(&key_once, make_key);
414408
if (pthread_getspecific(key)) {
415409
return -EEXIST;
416410
}
417-
return ctx_new(ctx_name, c, flags, userdata);
411+
return ctx_new(ctx_name, flags, userdata);
418412
}
419413

420-
_public_ int m_ctx_deregister(OUT m_ctx_t **c) {
421-
M_PARAM_ASSERT(c && *c && (*c)->state == M_CTX_IDLE);
422-
423-
int ret;
424-
m_ctx_t *context = *c;
414+
_public_ int m_ctx_deregister(void) {
415+
M_CTX_ASSERT();
416+
M_PARAM_ASSERT(c->state == M_CTX_IDLE);
425417

426-
ret = pthread_setspecific(key, NULL);
418+
int ret = pthread_setspecific(key, NULL);
427419
if (ret == 0) {
428-
context->state = M_CTX_ZOMBIE;
429-
m_iterate(context->modules, ctx_destroy_mods, NULL);
430-
*c = NULL;
420+
m_iterate(c->modules, ctx_destroy_mods, NULL);
421+
m_mem_unref(c);
431422
}
432-
m_mem_unref(context);
433423
return ret;
434424
}
435425

436-
_public_ int m_ctx_set_logger(m_ctx_t *c, m_log_cb logger) {
437-
M_CTX_ASSERT(c);
426+
_public_ int m_ctx_set_logger(m_log_cb logger) {
427+
M_CTX_ASSERT();
438428
M_PARAM_ASSERT(logger);
439429

440430
c->logger = logger;
441431
return 0;
442432
}
443433

444-
_public_ int m_ctx_loop(m_ctx_t *c) {
434+
_public_ int m_ctx_loop(void) {
435+
M_CTX_ASSERT();
445436
return m_ctx_loop_events(c, M_CTX_DEFAULT_EVENTS);
446437
}
447438

448-
_public_ int m_ctx_quit(m_ctx_t *c, uint8_t quit_code) {
449-
M_CTX_ASSERT(c);
439+
_public_ int m_ctx_quit(uint8_t quit_code) {
440+
M_CTX_ASSERT();
450441
M_LOG_ASSERT(c->state == M_CTX_LOOPING, "Context not looping.", -EINVAL);
451442

452443
return loop_quit(c, quit_code);
453444
}
454445

455-
_public_ int m_ctx_fd(const m_ctx_t *c) {
456-
M_CTX_ASSERT(c);
446+
_public_ int m_ctx_fd(void) {
447+
M_CTX_ASSERT();
457448

458449
return dup(poll_get_fd(&c->ppriv));
459450
}
460451

461-
_public_ int m_ctx_dispatch(m_ctx_t *c) {
462-
M_CTX_ASSERT(c);
452+
_public_ int m_ctx_dispatch(void) {
453+
M_CTX_ASSERT();
463454

464455
if (c->state == M_CTX_IDLE) {
465456
/* Ok, start now */
@@ -475,8 +466,8 @@ _public_ int m_ctx_dispatch(m_ctx_t *c) {
475466
return recv_events(c, 0);
476467
}
477468

478-
_public_ int m_ctx_dump(const m_ctx_t *c) {
479-
M_CTX_ASSERT(c);
469+
_public_ int m_ctx_dump(void) {
470+
M_CTX_ASSERT();
480471

481472
ctx_logger(c, NULL, "{\n");
482473
ctx_logger(c, NULL, "\t\"Name\": \"%s\",\n", c->name);
@@ -499,7 +490,7 @@ _public_ int m_ctx_dump(const m_ctx_t *c) {
499490
ctx_logger(c, NULL, "\t\t\"Busy_time\": %" PRIu64 ",\n", total_busy_time);
500491
ctx_logger(c, NULL, "\t\t\"Recv_events\": %" PRIu64 ",\n", c->stats.recv_msgs);
501492
ctx_logger(c, NULL, "\t\t\"Action_freq\": %lf,\n", (double)c->stats.recv_msgs / total_looping_time);
502-
ctx_logger(c, NULL, "\t\t\"Modules\": %lu,\n", m_ctx_len(c));
493+
ctx_logger(c, NULL, "\t\t\"Modules\": %lu,\n", m_ctx_len());
503494
ctx_logger(c, NULL, "\t\t\"Running_modules\": %lu\n", c->stats.running_modules);
504495
ctx_logger(c, NULL, "\t},\n");
505496

@@ -513,16 +504,16 @@ _public_ int m_ctx_dump(const m_ctx_t *c) {
513504
return 0;
514505
}
515506

516-
_public_ int m_ctx_stats(const m_ctx_t *c, OUT m_ctx_stats_t *stats) {
517-
M_CTX_ASSERT(c);
507+
_public_ int m_ctx_stats(OUT m_ctx_stats_t *stats) {
508+
M_CTX_ASSERT();
518509
M_PARAM_ASSERT(c->state == M_CTX_LOOPING);
519510
M_PARAM_ASSERT(stats);
520511

521512
uint64_t now;
522513
fetch_ms(&now, NULL);
523514

524515
stats->recv_msgs = c->stats.recv_msgs;
525-
stats->num_modules = m_ctx_len(c);
516+
stats->num_modules = m_ctx_len();
526517
stats->running_modules = c->stats.running_modules;
527518
stats->total_idle_time = c->stats.idle_time;
528519
stats->total_looping_time = now - c->stats.looping_start_time;
@@ -532,35 +523,35 @@ _public_ int m_ctx_stats(const m_ctx_t *c, OUT m_ctx_stats_t *stats) {
532523
return 0;
533524
}
534525

535-
_public_ const char *m_ctx_name(const m_ctx_t *c) {
526+
_public_ const char *m_ctx_name(void) {
527+
M_CTX();
536528
M_RET_ASSERT(c, NULL);
537-
M_RET_ASSERT(c->state != M_CTX_ZOMBIE, NULL);
538529

539530
return c->name;
540531
}
541532

542-
_public_ const void *m_ctx_userdata(const m_ctx_t *c) {
533+
_public_ const void *m_ctx_userdata(void) {
534+
M_CTX();
543535
M_RET_ASSERT(c, NULL);
544-
M_RET_ASSERT(c->state != M_CTX_ZOMBIE, NULL);
545536

546537
return c->userdata;
547538
}
548539

549-
_public_ ssize_t m_ctx_len(const m_ctx_t *c) {
550-
M_CTX_ASSERT(c);
540+
_public_ ssize_t m_ctx_len(void) {
541+
M_CTX_ASSERT();
551542

552543
return m_map_len(c->modules);
553544
}
554545

555-
_public_ int m_ctx_finalize(m_ctx_t *c) {
556-
M_CTX_ASSERT(c);
546+
_public_ int m_ctx_finalize(void) {
547+
M_CTX_ASSERT();
557548

558549
c->finalized = true;
559550
return 0;
560551
}
561552

562-
_public_ int m_ctx_set_tick(m_ctx_t *c, uint64_t ns) {
563-
M_CTX_ASSERT(c);
553+
_public_ int m_ctx_set_tick(uint64_t ns) {
554+
M_CTX_ASSERT();
564555

565556
deregister_ctx_src(c, &c->tick.src);
566557
if (ns != 0) {

Lib/core/ctx.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,15 @@
44
#include "public/module/structs/map.h"
55
#include "public/module/thpool/thpool.h"
66
#include "globals.h"
7+
#include "src.h"
78

89
#define M_CTX_DEFAULT_EVENTS 64
910

10-
// #define M_CTX() m_ctx_t *c = m_ctx();
11-
//
12-
// #define M_CTX_ASSERT(c) \
13-
// M_CTX(); \
14-
// M_RET_ASSERT(c, -EPIPE); \
15-
// M_RET_ASSERT(c->state != M_CTX_ZOMBIE, -EACCES)
11+
#define M_CTX() m_ctx_t *c = m_ctx();
1612

17-
#define M_CTX_ASSERT(c) \
18-
M_PARAM_ASSERT(c); \
19-
M_RET_ASSERT(c->state != M_CTX_ZOMBIE, -EACCES)
13+
#define M_CTX_ASSERT() \
14+
M_CTX(); \
15+
M_RET_ASSERT(c, -EPIPE)
2016

2117
typedef struct {
2218
void *data; // Context's poll priv data (depends upon poll_plugin)
@@ -34,7 +30,6 @@ typedef struct {
3430
typedef enum {
3531
M_CTX_IDLE,
3632
M_CTX_LOOPING,
37-
M_CTX_ZOMBIE,
3833
} m_ctx_states;
3934

4035
typedef struct {
@@ -67,4 +62,5 @@ struct _ctx {
6762
CONST const void *userdata; // Context's user defined data
6863
};
6964

65+
m_ctx_t *m_ctx(void);
7066
void ctx_logger(const m_ctx_t *c, const m_mod_t *mod, const char *fmt, ...);

Lib/core/fs/fs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ int fs_destroy(m_ctx_t *c) {
412412

413413
/** Public API **/
414414

415-
_public_ int m_ctx_fs_set_root(m_ctx_t *c, const char *path) {
416-
M_CTX_ASSERT(c);
415+
_public_ int m_ctx_fs_set_root(const char *path) {
416+
M_CTX_ASSERT();
417417
M_RET_ASSERT(c->state == M_CTX_IDLE, -EPERM);
418418
M_PARAM_ASSERT(str_not_empty(path));
419419
FS_PRIV();
@@ -423,8 +423,8 @@ _public_ int m_ctx_fs_set_root(m_ctx_t *c, const char *path) {
423423
return 0;
424424
}
425425

426-
_public_ int m_ctx_fs_set_ops(m_ctx_t *c, const struct fuse_operations *ops) {
427-
M_CTX_ASSERT(c);
426+
_public_ int m_ctx_fs_set_ops(const struct fuse_operations *ops) {
427+
M_CTX_ASSERT();
428428
M_RET_ASSERT(c->state == M_CTX_IDLE, -EPERM);
429429
M_PARAM_ASSERT(ops);
430430
FS_PRIV();

Lib/core/fs/fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include "public/module/mod.h"
4-
#include "public/module/ctx.h"
4+
#include "ctx.h"
55

66
int fs_create(m_ctx_t *c);
77
int fs_start(m_ctx_t *c);

Lib/core/main.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
* Code related to main library ctor/dtor + main() symbol. *
88
***********************************************************/
99

10-
_public_ _weak_ void m_ctx_pre_loop(m_ctx_t *c, int argc, char *argv[]) {
10+
_public_ _weak_ void m_ctx_pre_loop(int argc, char *argv[]) {
1111
M_DEBUG("Pre-looping libmodule easy API.\n");
1212
}
1313

14-
_public_ _weak_ void m_ctx_post_loop(m_ctx_t *c, int argc, char *argv[]) {
14+
_public_ _weak_ void m_ctx_post_loop(int argc, char *argv[]) {
1515
M_DEBUG("Post-looping libmodule easy API.\n");
1616
}
1717

@@ -23,15 +23,10 @@ _public_ _weak_ void m_ctx_post_loop(m_ctx_t *c, int argc, char *argv[]) {
2323
* All it does is looping on default ctx.
2424
*/
2525
_public_ _weak_ int main(int argc, char *argv[]) {
26-
m_ctx_t *c = m_ctx();
27-
if (!c) {
28-
M_ERR("No context available.\n");
29-
return EXIT_FAILURE;
30-
}
31-
m_ctx_pre_loop(c, argc, argv);
32-
const int ret = m_ctx_loop(c);
33-
m_ctx_post_loop(c, argc, argv);
34-
m_ctx_deregister(&c); // default_ctx may be NULL here, if eg: all modules where deregistered. We don't care
26+
m_ctx_pre_loop(argc, argv);
27+
const int ret = m_ctx_loop();
28+
m_ctx_post_loop(argc, argv);
29+
m_ctx_deregister(); // default_ctx may be NULL here, if eg: all modules where deregistered. We don't care
3530
return ret;
3631
}
3732

Lib/core/mod.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ int mod_deregister(m_mod_t **mod, bool from_user) {
328328
* it has no more modules in it and is not a persistent ctx
329329
*/
330330
if (c->state == M_CTX_IDLE && m_map_len(c->modules) == 0 && !(c->flags & M_CTX_PERSIST)) {
331-
ret = m_ctx_deregister(&c);
331+
ret = m_ctx_deregister();
332332
}
333333
}
334334
});
@@ -429,12 +429,12 @@ void mod_dump(const m_mod_t *mod, bool log_mod, const char *indent) {
429429

430430
/** Public API **/
431431

432-
_public_ int m_mod_register(const char *name, m_ctx_t *c, m_mod_t **mod_ref, const m_mod_hook_t *hook,
432+
_public_ int m_mod_register(const char *name, m_mod_t **mod_ref, const m_mod_hook_t *hook,
433433
m_mod_flags flags, const void *userdata) {
434434
M_PARAM_ASSERT(str_not_empty(name));
435435
/* Mandatory callback if hook is passed */
436436
M_PARAM_ASSERT(!hook || hook->on_evt);
437-
M_PARAM_ASSERT(c);
437+
M_CTX_ASSERT();
438438

439439
if (c->finalized) {
440440
return -EPERM;

Lib/core/mod.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ typedef struct {
4343
m_src_tmr_t timer;
4444
} mod_tb_t;
4545

46+
/* Forward declare ctx handler */
47+
typedef struct _ctx m_ctx_t;
48+
4649
/* Struct that holds data for each module */
4750
/*
4851
* MEM-REFS for mod:
@@ -70,7 +73,7 @@ struct _mod {
7073
m_map_t *subscriptions; // module's subscriptions (map of ev_src_t*)
7174
m_queue_t *stashed; // module's stashed messages
7275
m_list_t *bound_mods; // modules that are bound to this module's state
73-
CONST m_ctx_t *ctx; // Module's ctx
76+
CONST m_ctx_t *ctx; // Module's ctx -> even if ctx is threadspecific data, we need to know the context a module was registered into, to avoid user passing modules around to another thread/context
7477
};
7578

7679
int evaluate_module(void *data, const char *key, void *value);

Lib/core/public/module/cmn.h.in

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@
2121

2222
/** Structs types **/
2323

24-
/* Incomplete structure declaration to mod and ctx handlers */
24+
/* Incomplete structure declaration to mod handler */
2525
typedef struct _mod m_mod_t;
26-
typedef struct _ctx m_ctx_t;
2726

2827
/*
2928
* Common to any context; set this in m_on_boot(),

0 commit comments

Comments
 (0)