diff --git a/src/api.c b/src/api.c index ffdd96b..a35d180 100644 --- a/src/api.c +++ b/src/api.c @@ -5,19 +5,18 @@ #include "error.h" #include "init.h" #include "port.h" -#include "reflock-tree.h" +#include "thread-safe-tree.h" #include "util.h" #include "win.h" -static reflock_tree_t _epoll_handle_tree; +static ts_tree_t _epoll_handle_tree; -static inline ep_port_t* _handle_tree_node_to_port( - reflock_tree_node_t* tree_node) { +static inline ep_port_t* _handle_tree_node_to_port(ts_tree_node_t* tree_node) { return container_of(tree_node, ep_port_t, handle_tree_node); } int api_global_init(void) { - reflock_tree_init(&_epoll_handle_tree); + ts_tree_init(&_epoll_handle_tree); return 0; } @@ -32,9 +31,9 @@ static HANDLE _epoll_create(void) { if (port_info == NULL) return NULL; - if (reflock_tree_add(&_epoll_handle_tree, - &port_info->handle_tree_node, - (uintptr_t) ephnd) < 0) { + if (ts_tree_add(&_epoll_handle_tree, + &port_info->handle_tree_node, + (uintptr_t) ephnd) < 0) { /* This should never happen. */ ep_port_delete(port_info); return_error(NULL, ERROR_ALREADY_EXISTS); @@ -58,13 +57,13 @@ HANDLE epoll_create1(int flags) { } int epoll_close(HANDLE ephnd) { - reflock_tree_node_t* tree_node; + ts_tree_node_t* tree_node; ep_port_t* port_info; if (init() < 0) return -1; - tree_node = reflock_tree_del_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); + tree_node = ts_tree_del_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); if (tree_node == NULL) { err_set_win_error(ERROR_INVALID_PARAMETER); goto err; @@ -73,7 +72,7 @@ int epoll_close(HANDLE ephnd) { port_info = _handle_tree_node_to_port(tree_node); ep_port_close(port_info); - reflock_tree_node_unref_and_destroy(tree_node); + ts_tree_node_unref_and_destroy(tree_node); return ep_port_delete(port_info); @@ -83,15 +82,14 @@ err: } int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) { - reflock_tree_node_t* tree_node; + ts_tree_node_t* tree_node; ep_port_t* port_info; int r; if (init() < 0) return -1; - tree_node = - reflock_tree_find_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); + tree_node = ts_tree_find_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); if (tree_node == NULL) { err_set_win_error(ERROR_INVALID_PARAMETER); goto err; @@ -100,7 +98,7 @@ int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) { port_info = _handle_tree_node_to_port(tree_node); r = ep_port_ctl(port_info, op, sock, ev); - reflock_tree_node_unref(tree_node); + ts_tree_node_unref(tree_node); if (r < 0) goto err; @@ -119,7 +117,7 @@ int epoll_wait(HANDLE ephnd, struct epoll_event* events, int maxevents, int timeout) { - reflock_tree_node_t* tree_node; + ts_tree_node_t* tree_node; ep_port_t* port_info; int num_events; @@ -129,8 +127,7 @@ int epoll_wait(HANDLE ephnd, if (init() < 0) return -1; - tree_node = - reflock_tree_find_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); + tree_node = ts_tree_find_and_ref(&_epoll_handle_tree, (uintptr_t) ephnd); if (tree_node == NULL) { err_set_win_error(ERROR_INVALID_PARAMETER); goto err; @@ -139,7 +136,7 @@ int epoll_wait(HANDLE ephnd, port_info = _handle_tree_node_to_port(tree_node); num_events = ep_port_wait(port_info, events, maxevents, timeout); - reflock_tree_node_unref(tree_node); + ts_tree_node_unref(tree_node); if (num_events < 0) goto err; diff --git a/src/port.c b/src/port.c index 84ffd09..0459b9c 100644 --- a/src/port.c +++ b/src/port.c @@ -7,6 +7,7 @@ #include "port.h" #include "queue.h" #include "sock.h" +#include "thread-safe-tree.h" #include "tree.h" #include "util.h" #include "wepoll.h" @@ -54,7 +55,7 @@ ep_port_t* ep_port_new(HANDLE* iocp_out) { queue_init(&port_info->sock_update_queue); queue_init(&port_info->sock_deleted_queue); queue_init(&port_info->poll_group_queue); - reflock_tree_node_init(&port_info->handle_tree_node); + ts_tree_node_init(&port_info->handle_tree_node); InitializeCriticalSection(&port_info->lock); *iocp_out = iocp; diff --git a/src/port.h b/src/port.h index 472c2e3..c022387 100644 --- a/src/port.h +++ b/src/port.h @@ -5,8 +5,8 @@ #include "internal.h" #include "poll-group.h" #include "queue.h" -#include "reflock-tree.h" #include "sock.h" +#include "thread-safe-tree.h" #include "tree.h" #include "util.h" #include "win.h" @@ -20,7 +20,7 @@ typedef struct ep_port { queue_t sock_update_queue; queue_t sock_deleted_queue; queue_t poll_group_queue; - reflock_tree_node_t handle_tree_node; + ts_tree_node_t handle_tree_node; CRITICAL_SECTION lock; size_t active_poll_count; } ep_port_t; diff --git a/src/reflock-tree.c b/src/reflock-tree.c deleted file mode 100644 index a56001f..0000000 --- a/src/reflock-tree.c +++ /dev/null @@ -1,74 +0,0 @@ -#include - -#include "reflock-tree.h" -#include "reflock.h" -#include "tree.h" -#include "util.h" -#include "win.h" - -void reflock_tree_init(reflock_tree_t* rlt) { - tree_init(&rlt->tree); - InitializeSRWLock(&rlt->lock); -} - -void reflock_tree_node_init(reflock_tree_node_t* node) { - tree_node_init(&node->tree_node); - reflock_init(&node->reflock); -} - -int reflock_tree_add(reflock_tree_t* rlt, - reflock_tree_node_t* node, - uintptr_t key) { - int r; - - AcquireSRWLockExclusive(&rlt->lock); - r = tree_add(&rlt->tree, &node->tree_node, key); - ReleaseSRWLockExclusive(&rlt->lock); - - return r; -} - -reflock_tree_node_t* reflock_tree_del_and_ref(reflock_tree_t* rlt, - uintptr_t key) { - tree_node_t* tree_node; - reflock_tree_node_t* rlt_node; - - AcquireSRWLockExclusive(&rlt->lock); - - tree_node = tree_find(&rlt->tree, key); - rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node); - - if (rlt_node != NULL) { - tree_del(&rlt->tree, tree_node); - reflock_ref(&rlt_node->reflock); - } - - ReleaseSRWLockExclusive(&rlt->lock); - - return rlt_node; -} - -reflock_tree_node_t* reflock_tree_find_and_ref(reflock_tree_t* rlt, - uintptr_t key) { - tree_node_t* tree_node; - reflock_tree_node_t* rlt_node; - - AcquireSRWLockShared(&rlt->lock); - - tree_node = tree_find(&rlt->tree, key); - rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node); - if (rlt_node != NULL) - reflock_ref(&rlt_node->reflock); - - ReleaseSRWLockShared(&rlt->lock); - - return rlt_node; -} - -void reflock_tree_node_unref(reflock_tree_node_t* node) { - reflock_unref(&node->reflock); -} - -void reflock_tree_node_unref_and_destroy(reflock_tree_node_t* node) { - reflock_unref_and_destroy(&node->reflock); -} diff --git a/src/reflock-tree.h b/src/reflock-tree.h deleted file mode 100644 index 2b297c1..0000000 --- a/src/reflock-tree.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef WEPOLL_REFLOCK_TREE_H_ -#define WEPOLL_REFLOCK_TREE_H_ - -#include - -#include "internal.h" -#include "reflock.h" -#include "tree.h" -#include "win.h" - -typedef struct reflock_tree { - tree_t tree; - SRWLOCK lock; -} reflock_tree_t; - -typedef struct reflock_tree_node { - tree_node_t tree_node; - reflock_t reflock; -} reflock_tree_node_t; - -WEPOLL_INTERNAL void reflock_tree_init(reflock_tree_t* rtl); -WEPOLL_INTERNAL void reflock_tree_node_init(reflock_tree_node_t* node); - -WEPOLL_INTERNAL int reflock_tree_add(reflock_tree_t* rlt, - reflock_tree_node_t* node, - uintptr_t key); - -WEPOLL_INTERNAL reflock_tree_node_t* reflock_tree_del_and_ref( - reflock_tree_t* rlt, uintptr_t key); -WEPOLL_INTERNAL reflock_tree_node_t* reflock_tree_find_and_ref( - reflock_tree_t* rlt, uintptr_t key); - -WEPOLL_INTERNAL void reflock_tree_node_unref(reflock_tree_node_t* node); -WEPOLL_INTERNAL void reflock_tree_node_unref_and_destroy( - reflock_tree_node_t* node); - -#endif /* REFLOCK_TREE_H_ */ diff --git a/src/thread-safe-tree.c b/src/thread-safe-tree.c new file mode 100644 index 0000000..ce01e01 --- /dev/null +++ b/src/thread-safe-tree.c @@ -0,0 +1,70 @@ +#include + +#include "reflock.h" +#include "thread-safe-tree.h" +#include "tree.h" +#include "util.h" +#include "win.h" + +void ts_tree_init(ts_tree_t* ts_tree) { + tree_init(&ts_tree->tree); + InitializeSRWLock(&ts_tree->lock); +} + +void ts_tree_node_init(ts_tree_node_t* node) { + tree_node_init(&node->tree_node); + reflock_init(&node->reflock); +} + +int ts_tree_add(ts_tree_t* ts_tree, ts_tree_node_t* node, uintptr_t key) { + int r; + + AcquireSRWLockExclusive(&ts_tree->lock); + r = tree_add(&ts_tree->tree, &node->tree_node, key); + ReleaseSRWLockExclusive(&ts_tree->lock); + + return r; +} + +ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, uintptr_t key) { + tree_node_t* tree_node; + ts_tree_node_t* ts_tree_node; + + AcquireSRWLockExclusive(&ts_tree->lock); + + tree_node = tree_find(&ts_tree->tree, key); + ts_tree_node = safe_container_of(tree_node, ts_tree_node_t, tree_node); + + if (ts_tree_node != NULL) { + tree_del(&ts_tree->tree, tree_node); + reflock_ref(&ts_tree_node->reflock); + } + + ReleaseSRWLockExclusive(&ts_tree->lock); + + return ts_tree_node; +} + +ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, uintptr_t key) { + tree_node_t* tree_node; + ts_tree_node_t* ts_tree_node; + + AcquireSRWLockShared(&ts_tree->lock); + + tree_node = tree_find(&ts_tree->tree, key); + ts_tree_node = safe_container_of(tree_node, ts_tree_node_t, tree_node); + if (ts_tree_node != NULL) + reflock_ref(&ts_tree_node->reflock); + + ReleaseSRWLockShared(&ts_tree->lock); + + return ts_tree_node; +} + +void ts_tree_node_unref(ts_tree_node_t* node) { + reflock_unref(&node->reflock); +} + +void ts_tree_node_unref_and_destroy(ts_tree_node_t* node) { + reflock_unref_and_destroy(&node->reflock); +} diff --git a/src/thread-safe-tree.h b/src/thread-safe-tree.h new file mode 100644 index 0000000..8b4235d --- /dev/null +++ b/src/thread-safe-tree.h @@ -0,0 +1,36 @@ +#ifndef WEPOLL_THREAD_SAFE_TREE_H_ +#define WEPOLL_THREAD_SAFE_TREE_H_ + +#include + +#include "internal.h" +#include "reflock.h" +#include "tree.h" +#include "win.h" + +typedef struct ts_tree { + tree_t tree; + SRWLOCK lock; +} ts_tree_t; + +typedef struct ts_tree_node { + tree_node_t tree_node; + reflock_t reflock; +} ts_tree_node_t; + +WEPOLL_INTERNAL void ts_tree_init(ts_tree_t* rtl); +WEPOLL_INTERNAL void ts_tree_node_init(ts_tree_node_t* node); + +WEPOLL_INTERNAL int ts_tree_add(ts_tree_t* ts_tree, + ts_tree_node_t* node, + uintptr_t key); + +WEPOLL_INTERNAL ts_tree_node_t* ts_tree_del_and_ref(ts_tree_t* ts_tree, + uintptr_t key); +WEPOLL_INTERNAL ts_tree_node_t* ts_tree_find_and_ref(ts_tree_t* ts_tree, + uintptr_t key); + +WEPOLL_INTERNAL void ts_tree_node_unref(ts_tree_node_t* node); +WEPOLL_INTERNAL void ts_tree_node_unref_and_destroy(ts_tree_node_t* node); + +#endif /* WEPOLL_THREAD_SAFE_TREE_H_ */