void kore_platform_event_wait(void) { struct connection *c; int n, i, *fd; n = epoll_wait(efd, events, event_count, 100); if (n == -1) { if (errno == EINTR) return; fatal("epoll_wait(): %s", errno_s); } if (n > 0) kore_debug("main(): %d sockets available", n); for (i = 0; i < n; i++) { fd = (int *)events[i].data.ptr; if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP) { if (*fd == server.fd) fatal("error on server socket"); c = (struct connection *)events[i].data.ptr; kore_connection_disconnect(c); continue; } if (*fd == server.fd) { while (worker->accepted < worker->accept_treshold) { kore_connection_accept(&server, &c); if (c == NULL) break; worker->accepted++; kore_platform_event_schedule(c->fd, EPOLLIN | EPOLLOUT | EPOLLET, 0, c); } } else { c = (struct connection *)events[i].data.ptr; if (events[i].events & EPOLLIN) c->flags |= CONN_READ_POSSIBLE; if (events[i].events & EPOLLOUT && !(c->flags & CONN_WRITE_BLOCK)) c->flags |= CONN_WRITE_POSSIBLE; if (!kore_connection_handle(c)) kore_connection_disconnect(c); } } }
/* * Called for connection activity on a client, just forwards * to the default Kore connection handling for now. */ int client_handle(struct connection *c) { return (kore_connection_handle(c)); }
int kore_platform_event_wait(void) { struct connection *c; struct timespec timeo; int n, i, *fd; timeo.tv_sec = 0; timeo.tv_nsec = 100000000; n = kevent(kfd, changelist, nchanges, events, event_count, &timeo); if (n == -1) { if (errno == EINTR) return (0); fatal("kevent(): %s", errno_s); } nchanges = 0; if (n > 0) kore_debug("main(): %d sockets available", n); for (i = 0; i < n; i++) { fd = (int *)events[i].udata; if (events[i].flags & EV_EOF || events[i].flags & EV_ERROR) { if (*fd == server.fd) fatal("error on server socket"); c = (struct connection *)events[i].udata; kore_connection_disconnect(c); continue; } if (*fd == server.fd) { while (worker->accepted < worker->accept_treshold) { kore_connection_accept(&server, &c); if (c == NULL) continue; worker->accepted++; kore_platform_event_schedule(c->fd, EVFILT_READ, EV_ADD, c); kore_platform_event_schedule(c->fd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, c); } } else { c = (struct connection *)events[i].udata; if (events[i].filter == EVFILT_READ) c->flags |= CONN_READ_POSSIBLE; if (events[i].filter == EVFILT_WRITE) c->flags |= CONN_WRITE_POSSIBLE; if (!kore_connection_handle(c)) { kore_connection_disconnect(c); } else { if (!TAILQ_EMPTY(&(c->send_queue))) { kore_platform_event_schedule(c->fd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, c); } } } } return (count); }
/* * Called for connection activity on a backend, just forwards * to the default Kore connection handling for now. */ int backend_handle_default(struct connection *c) { return (kore_connection_handle(c)); }
/* * This function is called everytime a new event is triggered on the * connection. In this demo we just use it as a stub for the normal * callback kore_connection_handle(). * * In this callback you would generally look at the state of the connection * in c->state and perform the required actions like writing / reading using * net_send_flush() or net_recv_flush() if CONN_SEND_POSSIBLE or * CONN_READ_POSSIBLE are set respectively. Returning KORE_RESULT_ERROR from * this callback will disconnect the connection alltogether. */ int connection_handle(struct connection *c) { kore_log(LOG_NOTICE, "connection_handle: %p", c); return (kore_connection_handle(c)); }