From 28c8e4fab3e2ee7850bef888b5a50e0f74a4a390 Mon Sep 17 00:00:00 2001 From: Jacques de Laval Date: Tue, 22 Nov 2022 15:50:48 +0100 Subject: [PATCH] pev: Add callback private data destructor callback The private callback data is only available is only exposed in the API when a callback is called. In a scenario where the private data has been dynamically allocated on the heap and the event is deleted outside of the callback this is problematic since the user of the API has no way of deallocating this data. This patch adds a new optional callback that gets called during the deletion of an event. It is then possible to do what ever clean up is necessary in this callback. Signed-off-by: Jacques de Laval --- src/pev.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/pev.h | 18 ++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/pev.c b/src/pev.c index 1aaa28a..e1b7298 100644 --- a/src/pev.c +++ b/src/pev.c @@ -35,6 +35,7 @@ struct pev { }; void (*cb)(int, void *); + void (*cb_del)(void *); void *arg; }; @@ -97,6 +98,21 @@ int pev_sig_del(int id) return pev_sock_del(id); } +int pev_sig_set_cb_del(int id, void (*cb)(void *)) +{ + struct pev *entry; + + entry = pev_find(PEV_SIG, id); + if (!entry) { + errno = ENOENT; + return -1; + } + + entry->cb_del = cb; + + return 0; +} + /******************************* SOCKETS ******************************/ static int nfds(void) @@ -157,6 +173,9 @@ int pev_sock_del(int id) entry->active = 0; sig_handler(0); + if (entry->cb_del) + entry->cb_del(entry->arg); + return 0; } } @@ -200,6 +219,22 @@ int pev_sock_close(int sd) return 0; } +int pev_sock_set_cb_del(int id, void (*cb)(void *)) +{ + struct pev *entry; + + for (entry = pl; entry; entry = entry->next) { + if (entry->id == id) { + entry->cb_del = cb; + + return 0; + } + } + + errno = ENOENT; + return -1; +} + /******************************* TIMERS *******************************/ static struct pev *timer_ffs(void) @@ -396,6 +431,11 @@ int pev_timer_get(int id) return -1; } +int pev_timer_set_cb_del(int id, void (*cb)(void *)) +{ + return pev_sock_set_cb_del(id, cb); +} + /******************************* GENERIC ******************************/ static struct pev *pev_new(int type, void (*cb)(int, void *), void *arg) diff --git a/src/pev.h b/src/pev.h index 314d381..ad4589b 100644 --- a/src/pev.h +++ b/src/pev.h @@ -33,6 +33,12 @@ int pev_run (void); int pev_sig_add (int signo, void (*cb)(int, void *), void *arg); int pev_sig_del (int id); +/* + * Destructor callback, called when deleting a signal event (pev_sig_del). + * Useful for deallocating heap allocated arg data. + */ +int pev_sig_set_cb_del (int id, void (*cb)(void *)); + /* * Socket or file descriptor callback by sd/fd, only one callback per * descriptor. API changes to CLOEXEC and NONBLOCK. Delete by id @@ -48,6 +54,12 @@ int pev_sock_del (int id); int pev_sock_open (int domain, int type, int proto, void (*cb)(int, void *), void *arg); int pev_sock_close (int id); +/* + * Destructor callback, called when deleting a socket event (pev_sock_del or + * pev_sock_close). Useful for deallocating heap allocated arg data. + */ +int pev_sock_set_cb_del (int id, void (*cb)(void *)); + /* * Periodic timers use SIGALRM via setitimer() API, may affect use of * sleep(), usleep(), and alarm() APIs. See your respective OS for @@ -80,4 +92,10 @@ int pev_timer_del (int id); int pev_timer_set (int id, int timeout); int pev_timer_get (int id); +/* + * Destructor callback, called when deleting a timer (pev_timer_del). + * Useful for deallocating heap allocated arg data. + */ +int pev_timer_set_cb_del (int id, void (*cb)(void *)); + #endif /* PEV_H_ */