mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-06 07:15:30 -04:00
fdm: don't free FD data that may be referenced by epoll return data
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.
This commit is contained in:
parent
4ae22b72a1
commit
80c4721e57
2 changed files with 60 additions and 9 deletions
1
fdm.h
1
fdm.h
|
|
@ -11,5 +11,6 @@ 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue