void handle_event(int epfd, struct epoll_event ev) { struct fdinfo *fdinfo = ev.data.ptr; switch (fdinfo->type) { case LSOCK: accept_one(epfd, fdinfo->fd); break; case CLIENT: print_event(fdinfo->fd, ev); if (ev.events & EPOLLHUP) { kill_cli(epfd, fdinfo); return; } if (ev.events & EPOLLIN) { handle_cli(fdinfo); } if (ev.events & EPOLLRDHUP) { handle_cli(fdinfo); kill_cli(epfd, fdinfo); return; } break; } }
static int accept_connection_coro(struct coro *coro, void *data) { struct lwan *l = data; uint64_t cores = 0; while (coro_yield(coro, 1) & ~(EPOLLHUP | EPOLLRDHUP | EPOLLERR)) { enum herd_accept ha; do { ha = accept_one(l, &cores); } while (ha == HERD_MORE); if (UNLIKELY(ha > HERD_MORE)) break; if (LIKELY(cores)) { for (unsigned short t = 0; t < l->thread.count; t++) { if (cores & UINT64_C(1)<<t) lwan_thread_nudge(&l->thread.threads[t]); } cores = 0; } } return 0; }
static int accept_all(LEXER *l, const char *valid) { int n = 0; while (accept_one(l, valid)) n++; return n; }
static TOKEN lex_wildcard(LEXER *l) { l->f = lex_any; if (accept_one(l, ":") && accept_all(l, C_NUMERIC)) { return token(T_TYPE_ADDRESS, l); } return token(T_ERROR, NULL); }
static inline enum herd_accept accept_herd(struct lwan *l, uint64_t *cores) { enum herd_accept ha; if (!wait_herd()) return HERD_GONE; do { ha = accept_one(l, cores); } while (ha == HERD_MORE); return ha; }
void wait_for_players(fd_t server, fd_t * clients) { int client_count = 0; // Marking everyone as disconnected memset(clients, DISCONNECTED, sizeof(fd_t) * PLAYER_COUNT); // Waiting for everyone while (client_count < PLAYER_COUNT) { // Trying to accept a new client fd_t new_client = accept_one(server); if (new_client != DISCONNECTED) { add_client(clients, new_client); ++client_count; } // Checking for clients who left or got disconnected client_count -= dead_client_count(clients); } }
static TOKEN lex_numeric(LEXER *l) { /* supported numeric formats: \d+.\d+.\d+.\d+:\d+ is an ip:port (a BAREWORD) \d+.\d+.\d+.\d+ is an ip (another BAREWORD) \d+[kKmMgG]?b is a size \d+[smh] is a time \d+.\d+ is a decimal \d+ is an integer */ TOKEN t; char c; unsigned int ival = 0; l->f = lex_any; /* first let's see if this is in fact an IP address */ if (accept_all(l, C_NUMERIC) && accept_one(l, ".") && accept_all(l, C_NUMERIC) && accept_one(l, ".") && accept_all(l, C_NUMERIC) && accept_one(l, ".") && accept_all(l, C_NUMERIC)) { if (accept_one(l, ":") && !accept_all(l, C_NUMERIC)) { return token(T_ERROR, NULL); } return token(T_TYPE_ADDRESS, l); } restart(l); for (;;) { c = next(l); if (c == 0) { break; } if (strchr(C_NUMERIC, c) == NULL) { backup(l); break; } ival = ival * 10 + (c - '0'); } c = next(l); if (c == '.') { double factor = 10; double fval = ival; for (;;) { c = next(l); if (c == 0) { break; } if (strchr(C_NUMERIC, c) == NULL) { backup(l); break; } fval = fval + ((c - '0') / factor); factor *= 10; } t = token(T_TYPE_DECIMAL, l); t.semval.f = fval; return t; } if (strchr("kKmMgGbB", c) != NULL) { int factor = 1; switch (c) { case 'g': case 'G': factor *= 1024; case 'm': case 'M': factor *= 1024; case 'k': case 'K': factor *= 1024; } if (c != 'b' && c != 'B') { c = next(l); } if (c == 'b' || c == 'B') { t = token(T_TYPE_SIZE, l); t.semval.i = ival * factor; return t; } restart(l); } if (strchr("sSmMhH", c) != NULL) { int factor = 1; switch (c) { case 'h': case 'H': factor *= 60; case 'm': case 'M': factor *= 60; } t = token(T_TYPE_TIME, l); t.semval.i = ival * factor; return t; } backup(l); t = token(T_TYPE_INTEGER, l); t.semval.i = ival; return t; }
int main (int argc, char *argv[]) { int sd, ci, backlog = MAX_BACKLOG; short port = PORTNUM; if (argc > 1) ncons = atoi (argv[1]); /* decrease stack size, non-privilged operation */ /* shrink_stack (STACK_SIZE); not needed for parent */ /* increase maximum number of file descriptors, must be root! */ /* a few extra, for 0, 1, 2 etc. */ check_and_set_max_fd (ncons + 8); cd = malloc (ncons * sizeof (int)); isopen = malloc (ncons * sizeof (int)); pid = malloc (ncons * sizeof (pid_t)); gethostname (hostname, 128); signal (SIGCHLD, cleanupkids); /* open an internet tcp stream socket */ /* socket, setsockopt for reuse, bind, listen; */ sd = get_socket (port, backlog); for (ci = 0; ci < ncons; ci++) isopen[ci] = 0; for (;;) { /* accept new connection only if less than the maximum is there */ while (nopen == ncons) { /* reap any children; there may be a race condition or signal pileup! */ cleanupkids (SIGCHLD); } /* find the first open one */ ci = accept_one (sd, isopen, cd, ncons); isopen[ci] = 1; nopen++; printf ("connection accepted (cd[%2d] = %2d), nopen = %2d\n", ci, cd[ci], nopen); fflush (stdout); /* fork off a child to handle the connection */ pid[ci] = fork (); if (pid[ci] < 0) DEATH ("Forking"); if (pid[ci] == 0) { /* child */ /* decrease stack size, non-privilged operation */ shrink_stack (STACK_SIZE); /* can set back for kids */ set_max_fd (16); while (!handle_client (cd[ci])) ; terminate_client (ci); } else { /* parent */ printf (" I forked for ci=%d, pid=%d\n", ci, pid[ci]); fflush (stdout); } } close (sd); free (isopen); free (cd); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int sd, ci, n, backlog = MAX_BACKLOG, timeout = -1, nfds, nconsp1; short port = PORTNUM; struct pollfd *pfd, *pfd0; if (argc > 1) ncons = atoi (argv[1]); nconsp1 = ncons + 1; cd = malloc ((nconsp1 + 8) * sizeof (int)); isopen = malloc ((nconsp1 + 8) * sizeof (int)); ufds = malloc ((nconsp1 + 8) * sizeof (struct pollfd)); memset (ufds, 0, (nconsp1 + 8) * sizeof (struct pollfd)); /* increase maximum number of file descriptors, must be root! */ /* a few extra, for 0, 1, 2 etc. */ check_and_set_max_fd (nconsp1 + 8); gethostname (hostname, 128); /* open an internet tcp stream socket */ /* socket, setsockopt for reuse, bind, listen; */ sd = get_socket (port, backlog); /* for the listening socket */ pfd0 = &ufds[0]; pfd0->fd = sd; pfd0->events = POLLIN; isopen[0] = 0; for (ci = 1; ci < nconsp1 + 8; ci++) { pfd = &ufds[ci]; pfd->fd = -1; pfd->events = 0; isopen[ci] = 0; } for (;;) { /* wait for something to happen on one of the descriptors */ nfds = 1 + nopen; if (sd > fdmax) fdmax = sd; /* to begin with */ /* n = poll (ufds, nconsp1, timeout); */ n = poll (&ufds[0], fdmax + 1, timeout); if (n < 0) DEATH ("poll"); /* if you do a time out you have to deal with n = 0 */ /* accept new connection only if less than the maximum is there */ if ((pfd0->revents && POLLIN) && (nopen < ncons)) { isopen[0] = 1; /* find the first open one */ ci = accept_one (sd, isopen, cd, ncons); isopen[ci] = 1; pfd = &ufds[ci]; pfd->fd = cd[ci]; pfd->events = POLLIN; nopen++; if (cd[ci] > fdmax) fdmax = cd[ci]; printf ("connection accepted (cd[%2d] = %2d), nopen = %2d\n", ci, cd[ci], nopen); } /* service existing connections */ for (ci = 1; ci < nconsp1; ci++) { pfd = &ufds[ci]; if (isopen[ci] && (pfd->revents && POLLIN)) { if (handle_client (cd[ci])) terminate_client (ci); } fflush (stdout); } } close (sd); free (cd); free (isopen); exit (EXIT_SUCCESS); }
int main (int argc, char *argv[]) { int sd, ci, n, backlog = MAX_BACKLOG; short port = PORTNUM; if (argc > 1) ncons = atoi (argv[1]); if (ncons > FD_SETSIZE) DEATH ("Can't have more than 1024 for select(), and ulimit -s" " must be a bit larger") cd = malloc (ncons * sizeof (int)); isopen = malloc (ncons * sizeof (int)); gethostname (hostname, 128); /* open an internet tcp stream socket */ /* socket, setsockopt for reuse, bind, listen; */ sd = get_socket (port, backlog); for (ci = 0; ci < ncons; ci++) isopen[ci] = 0; FD_ZERO (&fdset); FD_SET (sd, &fdset); for (;;) { /* wait for something to happen on one of the descriptors */ testset = fdset; if (sd > fdmax) fdmax = sd; /* to begin with */ n = select (fdmax + 1, &testset, NULL, NULL, NULL); if (n < 0) DEATH ("select"); /* if you do a time out you have to deal with n = 0 */ /* accept new connection only if less than the maximum is there */ if (FD_ISSET (sd, &testset) && (nopen < ncons)) { /* find the first open one */ ci = accept_one (sd, isopen, cd, ncons); isopen[ci] = 1; FD_SET (cd[ci], &fdset); nopen++; if (cd[ci] > fdmax) fdmax = cd[ci]; printf ("connection accepted (cd[%2d] = %2d), nopen = %2d\n", ci, cd[ci], nopen); } /* service existing connections */ for (ci = 0; ci < ncons; ci++) { if (isopen[ci] && FD_ISSET (cd[ci], &testset)) if (handle_client (cd[ci])) terminate_client (ci); } } close (sd); free (cd); free (isopen); exit (EXIT_SUCCESS); }