mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
It is perfectly possible, and legal, for a FDM handler to delete another handler. The problem however is when the epoll returned array of FD events contain the removed FD handler *after* the handler that removed it. That is, if the epoll returned array is: [FD=13, FD=37] and the handler for FD=13 removes FD=37, then given the current implementation, the FD user data (our handler callback etc) will point to a free:d address. Add support for this situation by deferring FD handler removal *when called from another handler*. This is done by "locking" the FDM struct before looping the handlers for FDs with events (and unlocking afterwards). In fdm_del(), we check if the FDM has been locked, in which case the FD is marked as deleted, and put on a deferred list. But not *actually* deleted. Meanwhile, in the FDM poll function, we skip calling handlers for marked-for-deletion FDs. Then, when all FDs have been processed, we loop the deferred list and finally deletes the FDs for real.
16 lines
400 B
C
16 lines
400 B
C
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
|
|
struct fdm;
|
|
|
|
typedef bool (*fdm_handler_t)(struct fdm *fdm, int fd, int events, void *data);
|
|
|
|
struct fdm *fdm_init(void);
|
|
void fdm_destroy(struct fdm *fdm);
|
|
|
|
bool fdm_add(struct fdm *fdm, int fd, int events, fdm_handler_t handler, void *data);
|
|
bool fdm_del(struct fdm *fdm, int fd);
|
|
bool fdm_del_no_close(struct fdm *fdm, int fd);
|
|
|
|
bool fdm_poll(struct fdm *fdm);
|