io: catch double registration and unregistration bugs
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
2aef66006a
commit
81f4af6430
17
include/io.h
17
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);
|
||||
|
|
15
src/io.c
15
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);
|
||||
|
|
Reference in New Issue