Allow adding an event callback
This commit is contained in:
@@ -198,6 +198,7 @@ static void clear_res(struct io_resource *res)
|
||||
{
|
||||
res->type = IO_RES_VOID;
|
||||
res->pending = 0;
|
||||
res->callback = NULL;
|
||||
|
||||
#if IO_PLATFORM_WINDOWS
|
||||
res->os_handle = INVALID_HANDLE_VALUE;
|
||||
@@ -818,8 +819,8 @@ op_from_ov(struct io_os_overlap *ov)
|
||||
|
||||
#if IO_PLATFORM_WINDOWS
|
||||
static void
|
||||
io_wait_windows(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
io_wait_internal_windows(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
{
|
||||
int timeout = -1;
|
||||
|
||||
@@ -928,8 +929,8 @@ io_wait_windows(struct io_context *ioc,
|
||||
|
||||
#if IO_PLATFORM_LINUX
|
||||
static void
|
||||
io_wait_linux(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
io_wait_internal_linux(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
{
|
||||
/* --- Read barrier --- */
|
||||
unsigned int head = atomic_load(ioc->completions.head);
|
||||
@@ -984,8 +985,9 @@ io_wait_linux(struct io_context *ioc,
|
||||
}
|
||||
#endif
|
||||
|
||||
void io_wait(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
static void
|
||||
io_wait_internal(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
{
|
||||
#if IO_PLATFORM_WINDOWS
|
||||
io_wait_windows(ioc, ev);
|
||||
@@ -995,3 +997,37 @@ void io_wait(struct io_context *ioc,
|
||||
io_wait_linux(ioc, ev);
|
||||
#endif
|
||||
}
|
||||
|
||||
void io_wait(struct io_context *ioc,
|
||||
struct io_event *ev)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
io_wait_internal(ioc, ev);
|
||||
|
||||
if (ev->handle == IO_INVALID)
|
||||
break;
|
||||
|
||||
assert(ev->handle != IO_INVALID);
|
||||
|
||||
struct io_resource *res;
|
||||
res = res_from_handle(ioc, ev->handle);
|
||||
assert(res);
|
||||
|
||||
if (res->callback == NULL)
|
||||
break;
|
||||
|
||||
res->callback(*ev);
|
||||
}
|
||||
}
|
||||
|
||||
void io_set_callback(struct io_context *ioc,
|
||||
io_handle handle,
|
||||
io_callback callback)
|
||||
{
|
||||
struct io_resource *res;
|
||||
res = res_from_handle(ioc, handle);
|
||||
if (res == NULL)
|
||||
return;
|
||||
res->callback = callback;
|
||||
}
|
||||
@@ -63,18 +63,40 @@ struct io_operation {
|
||||
#endif
|
||||
};
|
||||
|
||||
enum io_evtype {
|
||||
IO_ERROR,
|
||||
IO_ABORT,
|
||||
IO_COMPLETE,
|
||||
};
|
||||
|
||||
struct io_event {
|
||||
enum io_evtype evtype;
|
||||
enum io_optype optype;
|
||||
io_handle handle;
|
||||
void *user;
|
||||
|
||||
union {
|
||||
uint32_t num;
|
||||
io_handle accepted;
|
||||
};
|
||||
};
|
||||
|
||||
enum io_restype {
|
||||
IO_RES_VOID,
|
||||
IO_RES_FILE,
|
||||
IO_RES_SOCKET,
|
||||
};
|
||||
|
||||
typedef void (*io_callback)(struct io_event);
|
||||
|
||||
struct io_resource {
|
||||
enum io_restype type;
|
||||
io_os_handle os_handle;
|
||||
uint16_t pending;
|
||||
uint16_t gen;
|
||||
|
||||
io_callback callback;
|
||||
|
||||
#if IO_PLATFORM_WINDOWS
|
||||
void *acceptfn;
|
||||
char accept_buffer[2 * (IO_SOCKADDR_IN_SIZE + 16)];
|
||||
@@ -121,24 +143,6 @@ struct io_context {
|
||||
#endif
|
||||
};
|
||||
|
||||
enum io_evtype {
|
||||
IO_ERROR,
|
||||
IO_ABORT,
|
||||
IO_COMPLETE,
|
||||
};
|
||||
|
||||
struct io_event {
|
||||
enum io_evtype evtype;
|
||||
enum io_optype optype;
|
||||
io_handle handle;
|
||||
void *user;
|
||||
|
||||
union {
|
||||
uint32_t num;
|
||||
io_handle accepted;
|
||||
};
|
||||
};
|
||||
|
||||
bool io_global_init(void);
|
||||
void io_global_free(void);
|
||||
|
||||
@@ -185,3 +189,7 @@ io_handle io_create_file(struct io_context *ioc,
|
||||
|
||||
io_handle io_start_server(struct io_context *ioc,
|
||||
const char *addr, int port);
|
||||
|
||||
void io_set_callback(struct io_context *ioc,
|
||||
io_handle handle,
|
||||
io_callback callback);
|
||||
Reference in New Issue
Block a user