+server_t * event_register(int fd, void *data)
+{
+ int fds[2];
+ if (fd == -1) {
+ if (pipe(fds) != 0) {
+ UNIXERR("pipe");
+ return NULL;
+ }
+ if (setnonblock(fds[0]) != 0) {
+ close(fds[0]);
+ close(fds[1]);
+ return NULL;
+ }
+ }
+
+ server_t *tmp = server_acquire();
+ tmp->listener = false;
+ tmp->event = true;
+ tmp->fd = fd == -1 ? fds[0] : fd;
+ tmp->fd2 = fd == -1 ? fds[1] : -1;
+ tmp->data = data;
+ epoll_register(fds[0], EPOLLIN, tmp);
+ return tmp;
+}
+
+bool event_fire(server_t *event)
+{
+ static const char *data = "";
+ if (event->fd2 == -1) {
+ return false;
+ }
+ return write(event->fd2, data, 1) == 0;
+}
+
+bool event_cancel(server_t *event)
+{
+ char buff[32];
+ while (true) {
+ ssize_t res = read(event->fd, buff, 32);
+ if (res == -1 && errno != EAGAIN && errno != EINTR) {
+ UNIXERR("read");
+ return false;
+ } else if (res == -1 && errno == EINTR) {
+ continue;
+ } else if (res != 32) {
+ return true;
+ }
+ }
+}
+
+void event_release(server_t *event)
+{
+ epoll_unregister(event->fd);
+ server_release(event);
+}
+