summaryrefslogtreecommitdiff
path: root/ot_event.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-26 20:03:22 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-26 20:03:22 +0100
commit2d6b6d4da1d9732b2b02989a4374d356ff840d1b (patch)
tree50ff9d2fba93934d1572706f10593aec0ea57e07 /ot_event.c
parentf2f5b0450d4b7269bafdfb1bd1788303f6d8ce7b (diff)
Replace libowfat's event waiter with our own abstraction
It's with a heavy heart that I remove libowfat as my event library from opentracker. libowfat is what taught opentracker to walk and then fly. The tracker was literally standing on the shoulder of giants when I started writing it in 2006. For its time, the event abstraction was unparalleled and it has held up for many years, and it served the bittorrent community greatly. https://erdgeist.org/gitweb/opentracker/commit/?id=ad472597c569568bad0526d116b601dfcb36638c Unfortunately, it is very likely that libowfat will not be maintained anymore for the foreseeable future, it is already not easy to get its source from upstream and opentracker started receiving bug reports that I can not reasonably answer or patch. Before the project gets more dependent on the limitations of libowfat's current state, I need to teach opentracker to stand on its own feet and fly by itself. I've learned a great deal in the process and have even more respect now for what libowfat pioneered. The path for opentracker is cleared now. Ground work has already been laid in the migration process to support multi threaded http processing while keeping the aggressive reduction of syscalls alive that made the libowfat+opentracker combo so scalable. Here be some dragons, though: Even though there is a unit test suite now, the event loop's rewrite has not been battle tested yet. So you might want to hold up for a bit before jumping on the solo band wagon. What awaits at the end will be a long overdue v1.0, which will be named in honour of Felix.
Diffstat (limited to 'ot_event.c')
-rw-r--r--ot_event.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/ot_event.c b/ot_event.c
index d24227d..ce0feef 100644
--- a/ot_event.c
+++ b/ot_event.c
@@ -60,7 +60,7 @@ static int event_ctl(int op, int fd, int what, uint32_t generation) {
60 struct epoll_event ev; 60 struct epoll_event ev;
61 61
62 memset(&ev, 0, sizeof(ev)); 62 memset(&ev, 0, sizeof(ev));
63 ev.events = (what & EVENT_READ ? (uint32_t)EPOLLIN : 0) | (what & EVENT_WRITE ? (uint32_t)EPOLLOUT : 0); 63 ev.events = (what & EVENT_IN ? (uint32_t)EPOLLIN : 0) | (what & EVENT_OUT ? (uint32_t)EPOLLOUT : 0);
64 /* The generation rides along inside the kernel, so an event says which 64 /* The generation rides along inside the kernel, so an event says which
65 connection it belongs to without anybody looking it up */ 65 connection it belongs to without anybody looking it up */
66 ev.data.u64 = ((uint64_t)generation << 32) | (uint32_t)fd; 66 ev.data.u64 = ((uint64_t)generation << 32) | (uint32_t)fd;
@@ -92,8 +92,8 @@ int event_wait(ot_event *out, int max, int timeout_ms) {
92 out[i].generation = (uint32_t)(g_ready[i].data.u64 >> 32); 92 out[i].generation = (uint32_t)(g_ready[i].data.u64 >> 32);
93 /* A hangup or an error is reported as both, so whichever side the caller 93 /* A hangup or an error is reported as both, so whichever side the caller
94 was waiting on gets to notice */ 94 was waiting on gets to notice */
95 out[i].what = (events & (EPOLLIN | EPOLLHUP | EPOLLERR) ? EVENT_READ : 0) | 95 out[i].what = (events & (EPOLLIN | EPOLLHUP | EPOLLERR) ? EVENT_IN : 0) |
96 (events & (EPOLLOUT | EPOLLHUP | EPOLLERR) ? EVENT_WRITE : 0); 96 (events & (EPOLLOUT | EPOLLHUP | EPOLLERR) ? EVENT_OUT : 0);
97 } 97 }
98 return count; 98 return count;
99} 99}
@@ -138,9 +138,9 @@ static int event_change(int fd, int what, uint32_t generation, int deleting) {
138 int succeeded = 0, count, i; 138 int succeeded = 0, count, i;
139 139
140 EV_SET(&change[0], (uintptr_t)fd, EVFILT_READ, 140 EV_SET(&change[0], (uintptr_t)fd, EVFILT_READ,
141 EV_RECEIPT | ((deleting || !(what & EVENT_READ)) ? EV_DELETE : EV_ADD), 0, 0, udata); 141 EV_RECEIPT | ((deleting || !(what & EVENT_IN)) ? EV_DELETE : EV_ADD), 0, 0, udata);
142 EV_SET(&change[1], (uintptr_t)fd, EVFILT_WRITE, 142 EV_SET(&change[1], (uintptr_t)fd, EVFILT_WRITE,
143 EV_RECEIPT | ((deleting || !(what & EVENT_WRITE)) ? EV_DELETE : EV_ADD), 0, 0, udata); 143 EV_RECEIPT | ((deleting || !(what & EVENT_OUT)) ? EV_DELETE : EV_ADD), 0, 0, udata);
144 144
145 if ((count = kevent(g_kqueue, change, 2, result, 2, NULL)) == -1) 145 if ((count = kevent(g_kqueue, change, 2, result, 2, NULL)) == -1)
146 return -1; 146 return -1;
@@ -197,8 +197,8 @@ int event_wait(ot_event *out, int max, int timeout_ms) {
197 197
198 out[i].fd = (int)(uint32_t)udata; 198 out[i].fd = (int)(uint32_t)udata;
199 out[i].generation = (uint32_t)(udata >> 32); 199 out[i].generation = (uint32_t)(udata >> 32);
200 out[i].what = ((g_ready[i].filter == EVFILT_READ || eof) ? EVENT_READ : 0) | 200 out[i].what = ((g_ready[i].filter == EVFILT_READ || eof) ? EVENT_IN : 0) |
201 ((g_ready[i].filter == EVFILT_WRITE || eof) ? EVENT_WRITE : 0); 201 ((g_ready[i].filter == EVFILT_WRITE || eof) ? EVENT_OUT : 0);
202 } 202 }
203 return count; 203 return count;
204} 204}
@@ -232,7 +232,7 @@ void event_deinit(void) {
232} 232}
233 233
234static short event_to_poll(int what) { 234static short event_to_poll(int what) {
235 return (short)((what & EVENT_READ ? POLLIN : 0) | (what & EVENT_WRITE ? POLLOUT : 0)); 235 return (short)((what & EVENT_IN ? POLLIN : 0) | (what & EVENT_OUT ? POLLOUT : 0));
236} 236}
237 237
238static int event_room_for(int fd) { 238static int event_room_for(int fd) {
@@ -322,8 +322,8 @@ int event_wait(ot_event *out, int max, int timeout_ms) {
322 continue; 322 continue;
323 out[found].fd = g_pfds[i].fd; 323 out[found].fd = g_pfds[i].fd;
324 out[found].generation = g_generation[i]; 324 out[found].generation = g_generation[i];
325 out[found].what = (revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL) ? EVENT_READ : 0) | 325 out[found].what = (revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL) ? EVENT_IN : 0) |
326 (revents & (POLLOUT | POLLHUP | POLLERR | POLLNVAL) ? EVENT_WRITE : 0); 326 (revents & (POLLOUT | POLLHUP | POLLERR | POLLNVAL) ? EVENT_OUT : 0);
327 ++found; 327 ++found;
328 } 328 }
329 return found; 329 return found;