initial commit
This commit is contained in:
167
third_party/libhv/event/rudp.c
vendored
Executable file
167
third_party/libhv/event/rudp.c
vendored
Executable file
@@ -0,0 +1,167 @@
|
||||
#include "rudp.h"
|
||||
|
||||
#if WITH_RUDP
|
||||
|
||||
#include "hevent.h"
|
||||
|
||||
void rudp_entry_free(rudp_entry_t* entry) {
|
||||
#if WITH_KCP
|
||||
kcp_release(&entry->kcp);
|
||||
#endif
|
||||
HV_FREE(entry);
|
||||
}
|
||||
|
||||
void rudp_init(rudp_t* rudp) {
|
||||
// printf("rudp init\n");
|
||||
rudp->rb_root.rb_node = NULL;
|
||||
hmutex_init(&rudp->mutex);
|
||||
}
|
||||
|
||||
void rudp_cleanup(rudp_t* rudp) {
|
||||
// printf("rudp cleaup\n");
|
||||
struct rb_node* n = NULL;
|
||||
rudp_entry_t* e = NULL;
|
||||
while ((n = rudp->rb_root.rb_node)) {
|
||||
e = rb_entry(n, rudp_entry_t, rb_node);
|
||||
rb_erase(n, &rudp->rb_root);
|
||||
rudp_entry_free(e);
|
||||
}
|
||||
hmutex_destroy(&rudp->mutex);
|
||||
}
|
||||
|
||||
bool rudp_insert(rudp_t* rudp, rudp_entry_t* entry) {
|
||||
struct rb_node** n = &rudp->rb_root.rb_node;
|
||||
struct rb_node* parent = NULL;
|
||||
rudp_entry_t* e = NULL;
|
||||
int cmp = 0;
|
||||
bool exists = false;
|
||||
while (*n) {
|
||||
parent = *n;
|
||||
e = rb_entry(*n, rudp_entry_t, rb_node);
|
||||
cmp = memcmp(&entry->addr, &e->addr, sizeof(sockaddr_u));
|
||||
if (cmp < 0) {
|
||||
n = &(*n)->rb_left;
|
||||
} else if (cmp > 0) {
|
||||
n = &(*n)->rb_right;
|
||||
} else {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
rb_link_node(&entry->rb_node, parent, n);
|
||||
rb_insert_color(&entry->rb_node, &rudp->rb_root);
|
||||
}
|
||||
return !exists;
|
||||
}
|
||||
|
||||
rudp_entry_t* rudp_search(rudp_t* rudp, struct sockaddr* addr) {
|
||||
struct rb_node* n = rudp->rb_root.rb_node;
|
||||
rudp_entry_t* e = NULL;
|
||||
int cmp = 0;
|
||||
bool exists = false;
|
||||
while (n) {
|
||||
e = rb_entry(n, rudp_entry_t, rb_node);
|
||||
cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u));
|
||||
if (cmp < 0) {
|
||||
n = n->rb_left;
|
||||
} else if (cmp > 0) {
|
||||
n = n->rb_right;
|
||||
} else {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return exists ? e : NULL;
|
||||
}
|
||||
|
||||
rudp_entry_t* rudp_remove(rudp_t* rudp, struct sockaddr* addr) {
|
||||
hmutex_lock(&rudp->mutex);
|
||||
rudp_entry_t* e = rudp_search(rudp, addr);
|
||||
if (e) {
|
||||
// printf("rudp_remove ");
|
||||
// SOCKADDR_PRINT(addr);
|
||||
rb_erase(&e->rb_node, &rudp->rb_root);
|
||||
}
|
||||
hmutex_unlock(&rudp->mutex);
|
||||
return e;
|
||||
}
|
||||
|
||||
rudp_entry_t* rudp_get(rudp_t* rudp, struct sockaddr* addr) {
|
||||
hmutex_lock(&rudp->mutex);
|
||||
struct rb_node** n = &rudp->rb_root.rb_node;
|
||||
struct rb_node* parent = NULL;
|
||||
rudp_entry_t* e = NULL;
|
||||
int cmp = 0;
|
||||
bool exists = false;
|
||||
// search
|
||||
while (*n) {
|
||||
parent = *n;
|
||||
e = rb_entry(*n, rudp_entry_t, rb_node);
|
||||
cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u));
|
||||
if (cmp < 0) {
|
||||
n = &(*n)->rb_left;
|
||||
} else if (cmp > 0) {
|
||||
n = &(*n)->rb_right;
|
||||
} else {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
// insert
|
||||
// printf("rudp_insert ");
|
||||
// SOCKADDR_PRINT(addr);
|
||||
HV_ALLOC_SIZEOF(e);
|
||||
memcpy(&e->addr, addr, SOCKADDR_LEN(addr));
|
||||
rb_link_node(&e->rb_node, parent, n);
|
||||
rb_insert_color(&e->rb_node, &rudp->rb_root);
|
||||
}
|
||||
hmutex_unlock(&rudp->mutex);
|
||||
return e;
|
||||
}
|
||||
|
||||
void rudp_del(rudp_t* rudp, struct sockaddr* addr) {
|
||||
hmutex_lock(&rudp->mutex);
|
||||
rudp_entry_t* e = rudp_search(rudp, addr);
|
||||
if (e) {
|
||||
// printf("rudp_remove ");
|
||||
// SOCKADDR_PRINT(addr);
|
||||
rb_erase(&e->rb_node, &rudp->rb_root);
|
||||
rudp_entry_free(e);
|
||||
}
|
||||
hmutex_unlock(&rudp->mutex);
|
||||
}
|
||||
|
||||
rudp_entry_t* hio_get_rudp(hio_t* io) {
|
||||
rudp_entry_t* rudp = rudp_get(&io->rudp, io->peeraddr);
|
||||
rudp->io = io;
|
||||
return rudp;
|
||||
}
|
||||
|
||||
static void hio_close_rudp_event_cb(hevent_t* ev) {
|
||||
rudp_entry_t* entry = (rudp_entry_t*)ev->userdata;
|
||||
rudp_del(&entry->io->rudp, (struct sockaddr*)&entry->addr);
|
||||
// rudp_entry_free(entry);
|
||||
}
|
||||
|
||||
int hio_close_rudp(hio_t* io, struct sockaddr* peeraddr) {
|
||||
if (peeraddr == NULL) peeraddr = io->peeraddr;
|
||||
// NOTE: do rudp_del for thread-safe
|
||||
rudp_entry_t* entry = rudp_get(&io->rudp, peeraddr);
|
||||
// NOTE: just rudp_remove first, do rudp_entry_free async for safe.
|
||||
// rudp_entry_t* entry = rudp_remove(&io->rudp, peeraddr);
|
||||
if (entry) {
|
||||
hevent_t ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.cb = hio_close_rudp_event_cb;
|
||||
ev.userdata = entry;
|
||||
ev.priority = HEVENT_HIGH_PRIORITY;
|
||||
hloop_post_event(io->loop, &ev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user