void conn_close(struct conn *c) { /* delete the event, the socket and the conn */ event_del(&c->event); log_debug(LOG_VVERB, "<%d connection closed", c->sd); close(c->sd); core_accept_conns(true); conn_cleanup(c); conn_put(c); stats_thread_decr(conn_curr); return; }
void conn_close(conn *c) { assert(c != NULL); /* delete the event, the socket and the conn */ event_del(&c->event); if (settings.verbose > 1) fprintf(stderr, "<%d connection closed.\n", c->sfd); close(c->sfd); accept_new_conns(true); conn_cleanup(c); /* if the connection has big buffers, just free it */ if (c->rsize > READ_BUFFER_HIGHWAT || conn_add_to_freelist(c)) { conn_free(c); } return; }
void drive_machine(conn *c) { bool stop = false; int sfd, flags = 1; socklen_t addrlen; struct sockaddr_storage addr; struct linger ling = { 1, 0 }; int res; assert(c != NULL); while (!stop) { switch (c->state) { case conn_listening: addrlen = sizeof(addr); if ((sfd = accept(c->sfd, (struct sockaddr *) &addr, &addrlen)) == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { /* these are transient, so don't log anything */ stop = true; } else if (errno == EMFILE) { if (settings.verbose > 0) fprintf(stderr, "Too many open connections\n"); accept_new_conns(false); stop = true; } else { perror("accept()"); stop = true; } break; } if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("setting O_NONBLOCK"); close(sfd); break; } DEBUG_LOGGER(dsmplog, "accept new socket[%d], wait for request", sfd); setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *) &flags, sizeof(flags)); setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *) &ling, sizeof(ling)); dispatch_conn_new(sfd, conn_read, EV_READ | EV_PERSIST, DATA_BUFFER_SIZE, false); break; case conn_read: //DEBUG_LOGGER(dsmplog, "-------------socket [%d] has incoming data-------------", c->sfd); if (try_read_cli(c)) { //数据处理完毕,可以读取下一个请求包 continue; } if (try_read_tcp(c)) { continue; } /* we have no command line and no data to read from network */ if (!update_event(c, EV_READ | EV_PERSIST)) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); break; } stop = true; break; case conn_closing: if (c->udp) conn_cleanup(c); else conn_close(c); stop = true; break; } } return; }