summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-07-28 00:31:26 +0200
committerPatrick McHardy <kaber@trash.net>2010-07-28 02:05:46 +0200
commit81f4af6430b0d6c63039199b2b788f0945bcea6e (patch)
treef7933d020a763e179160c3884d343c5f7165070e
parent2aef66006a9c43aa0eea99396e47dd623e3683a8 (diff)
io: catch double registration and unregistration bugs
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/io.h17
-rw-r--r--src/io.c15
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);
diff --git a/src/io.c b/src/io.c
index 9c6705f..ff1b200 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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);