diff options
author | Patrick McHardy <kaber@trash.net> | 2010-07-28 00:31:26 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-07-28 02:05:46 +0200 |
commit | 81f4af6430b0d6c63039199b2b788f0945bcea6e (patch) | |
tree | f7933d020a763e179160c3884d343c5f7165070e | |
parent | 2aef66006a9c43aa0eea99396e47dd623e3683a8 (diff) |
io: catch double registration and unregistration bugs
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/io.h | 17 | ||||
-rw-r--r-- | src/io.c | 15 |
2 files changed, 25 insertions, 7 deletions
diff --git a/include/io.h b/include/io.h index 5aaea18..5d8c289 100644 --- a/include/io.h +++ b/include/io.h @@ -10,20 +10,27 @@ #include <sys/socket.h> #include <utils.h> +enum dect_fd_state { + DECT_FD_UNREGISTERED, + DECT_FD_REGISTERED, +}; + /** * struct dect_fd - libdect file descriptor * * @callback: callback to invoke for events * @fd: file descriptor numer + * @state: file descriptor registration state (debugging) * @data: libdect internal data * @priv: libdect user private file-descriptor storage */ struct dect_fd { - void (*callback)(struct dect_handle *, - struct dect_fd *, uint32_t); - int fd; - void *data; - uint8_t priv[] __aligned(__alignof__(uint64_t)); + void (*callback)(struct dect_handle *, + struct dect_fd *, uint32_t); + int fd; + enum dect_fd_state state; + void *data; + uint8_t priv[] __aligned(__alignof__(uint64_t)); }; extern struct dect_fd *dect_alloc_fd(const struct dect_handle *dh); @@ -57,7 +57,8 @@ struct dect_fd *dect_alloc_fd(const struct dect_handle *dh) dh->ops->event_ops->fd_priv_size); if (dfd == NULL) return NULL; - dfd->fd = -1; + dfd->fd = -1; + dfd->state = DECT_FD_UNREGISTERED; return dfd; } EXPORT_SYMBOL(dect_alloc_fd); @@ -96,13 +97,21 @@ EXPORT_SYMBOL(dect_setup_fd); int dect_register_fd(const struct dect_handle *dh, struct dect_fd *dfd, uint32_t events) { - return dh->ops->event_ops->register_fd(dh, dfd, events); + int err; + + assert(dfd->state == DECT_FD_UNREGISTERED); + err = dh->ops->event_ops->register_fd(dh, dfd, events); + if (err == 0) + dfd->state = DECT_FD_REGISTERED; + return err; } EXPORT_SYMBOL(dect_register_fd); void dect_unregister_fd(const struct dect_handle *dh, struct dect_fd *dfd) { + assert(dfd->state == DECT_FD_REGISTERED); dh->ops->event_ops->unregister_fd(dh, dfd); + dfd->state = DECT_FD_UNREGISTERED; } EXPORT_SYMBOL(dect_unregister_fd); @@ -118,12 +127,14 @@ EXPORT_SYMBOL(dect_unregister_fd); */ void dect_handle_fd(struct dect_handle *dh, struct dect_fd *dfd, uint32_t events) { + assert(dfd->state == DECT_FD_REGISTERED); dfd->callback(dh, dfd, events); } EXPORT_SYMBOL(dect_handle_fd); void dect_close(const struct dect_handle *dh, struct dect_fd *dfd) { + assert(dfd->state == DECT_FD_UNREGISTERED); if (dfd->fd >= 0) close(dfd->fd); dect_free(dh, dfd); |