int transfer_listening_sockets (struct mc_config *MC, struct mc_config *MC_Old) { int i, j, k; for (i = 0; i < MC->clusters_num; i++) { struct mc_cluster *C = &MC->Clusters[i]; j = C->other_cluster_no; if (j >= 0) { assert (j < MC_Old->clusters_num); struct mc_cluster *OC = &MC_Old->Clusters[j]; assert (OC->port == C->port && OC->other_cluster_no == i); C->server_socket = OC->server_socket; C->listening_connection = OC->listening_connection; OC->server_socket = -1; OC->listening_connection = 0; C->listening_connection->extra = &C->mc_proxy_inbound; } else { assert (init_listening_connection (C->server_socket, &ct_memcache_server, &C->mc_proxy_inbound) >= 0); C->listening_connection = Connections + C->server_socket; } } for (k = 0; k <= max_connection; k++) { struct connection *c = Connections + k; if (c->basic_type != ct_inbound || c->fd != k) { continue; } struct mc_cluster *OC = ((struct memcache_server_functions *) c->extra)->info; assert (OC && &OC->mc_proxy_inbound == c->extra); j = OC->cluster_no; i = OC->other_cluster_no; assert (OC == &MC_Old->Clusters[j]); if (i >= 0) { struct mc_cluster *C = &MC->Clusters[i]; assert (C->cluster_no == i && C->other_cluster_no == j); vkprintf (2, "transferring inbound connection #%d (port %d) from old cluster %d to new cluster %d\n", k, OC->port, j, i); c->extra = &C->mc_proxy_inbound; } else { vkprintf (2, "closing inbound connection #%d (port %d) belonging to old cluster %d, no new cluster\n", k, OC->port, j); force_clear_connection (c); epoll_close (k); close (k); } } for (i = 0; i < MC_Old->clusters_num; i++) { struct mc_cluster *OC = &MC_Old->Clusters[i]; if (OC->other_cluster_no == -1) { assert (OC->server_socket >= 0); k = OC->server_socket; vkprintf (1, "closing unneeded listening connection #%d for port %d belonging to old cluster %d (%s)\n", k, OC->port, i, OC->cluster_name); force_clear_connection (&Connections[k]); epoll_close (k); close (k); OC->server_socket = -1; OC->listening_connection = 0; } else { assert (OC->server_socket == -1 && !OC->listening_connection); } } return 0; }
void epoll_cleanup() { GUARD(); WSACleanup(); for(std::map<int, ep_internal>::iterator itr = ep_data.begin(); itr != ep_data.end(); ++itr) epoll_close(itr->first); ep_data.clear(); }
void do_epoll(int fd_server) { epoll_t my_epoll; epoll_init(&my_epoll, fd_server, handler); while(1){ epoll_wait_signal(&my_epoll); epoll_handle(&my_epoll); } epoll_close(&my_epoll); }
void server_exit (engine_t *E) { epoll_close (E->sfd); close (E->sfd); flush_binlog_last (); sync_binlog (2); if (pending_signals & (1 << SIGTERM)) { kprintf ("Terminated by SIGTERM.\n"); } else if (pending_signals & (1 << SIGINT)) { kprintf ("Terminated by SIGINT.\n"); } }
void do_epoll(int listenfd) { epoll_t pol; epoll_init(&pol, listenfd, handle); while(1) { epoll_do_wait(&pol); epoll_handle(&pol); } epoll_close(&pol); }
int main(void) { static const char HELLO[] = "hello, world!"; HANDLE epoll_port; SOCKET send_sock, recv_sock; { /* Create an epoll instance. */ epoll_port = epoll_create(1); check(epoll_port != NULL); } { /* Create a TCP socket pair. */ SOCKET socks[2]; int r = tcp_socketpair(socks); check(r == 0); send_sock = socks[0]; recv_sock = socks[1]; } { /* Enable non-blocking mode on the receiving end. */ int r = sock_set_nonblock(recv_sock, true); check(r == 0); } { /* Send some data in order to trigger an event on the receiving socket. */ int r = send(send_sock, HELLO, sizeof HELLO, 0); check(r == sizeof HELLO); } { /* Add the receiving socket to the epoll set. */ struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, recv_sock, &ev); check(r >= 0); } { /* Receive the EPOLLIN event for recv_sock. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLIN); check(ev.data.sock == recv_sock); } { /* Read the data from the socket. */ char buffer[16]; int r = recv(recv_sock, buffer, sizeof buffer, 0); check(r > 0); } { /* Since the last epoll_ctl() call specified the EPOLLONESOT flag, * no events should be reported here -- neither EPOLLIN nor EPOLLHUP. */ static const int timeout = 250; /* Quarter second. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, timeout); check(r == 0); /* Time-out. */ } { /* Attempt to EPOLL_CTL_ADD the socket to the port. This should fail, * because EPOLLONESHOT causes events to be disabled after one is reported, * but the socket should not be dropped from the epoll set. */ struct epoll_event ev; int r; ev.events = EPOLLIN | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, recv_sock, &ev); check(r == -1); check(errno == EEXIST); check(GetLastError() == ERROR_ALREADY_EXISTS); } { /* Modify the read socket event mask to EPOLLRDHUP. */ struct epoll_event ev; int r; ev.events = EPOLLRDHUP | EPOLLONESHOT; ev.data.sock = recv_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_MOD, recv_sock, &ev); check(r == 0); } { /* Send some data, which will never be read by the receiving end, otherwise * Windows won't detect that the connection is closed. */ int r = send(send_sock, HELLO, sizeof HELLO, 0); check(r == sizeof HELLO); } { /* Send FIN packet. */ int r = shutdown(send_sock, SD_SEND); check(r == 0); } { /* Receive the EPOLLRDHUP event for recv_sock. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLRDHUP); check(ev.data.sock == recv_sock); } { /* Close to receiving socket, so the sending socket should detect a * connection hang-up */ int r = closesocket(recv_sock); check(r == 0); } { /* Add the *write* socket to the epoll set. The event mask is empty, but * since EPOLLHUP and EPOLLERR are always reportable, the next call to * epoll_wait() should detect that the connection has been closed. */ struct epoll_event ev; int r; ev.events = 0; ev.data.sock = send_sock; r = epoll_ctl(epoll_port, EPOLL_CTL_ADD, send_sock, &ev); check(r == 0); } { /* Receive the EPOLLHUP event for write end of the connection. */ struct epoll_event ev; int r; memset(&ev, 0, sizeof ev); r = epoll_wait(epoll_port, &ev, 1, -1); check(r == 1); check(ev.events == EPOLLHUP); check(ev.data.sock == send_sock); } { /* Close the send socket. */ int r = closesocket(send_sock); check(r == 0); } { /* Close the epoll port. */ int r = epoll_close(epoll_port); check(r == 0); } return 0; }
void start_server (void) { char buf[64]; int i, prev_time = 0; init_epoll (); init_netbuffers (); if (!sfd) { sfd = server_socket (port, settings_addr, backlog, 0); } if (sfd < 0) { kprintf ("cannot open server socket at port %d: %m\n", port); exit (3); } vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, buf), port, sfd); if (daemonize) { setsid (); } if (change_user (username) < 0) { kprintf ("fatal: cannot change user to %s\n", username ? username : "******"); exit (1); } if (binlogname && !binlog_disabled) { assert (append_to_binlog (Binlog) == log_readto_pos); } init_listening_connection (sfd, &ct_rpc_server, ©exec_result_rpc_server); sigset_t signal_set; sigemptyset (&signal_set); sigaddset (&signal_set, SIGINT); sigaddset (&signal_set, SIGTERM); sigaddset (&signal_set, SIGUSR1); if (daemonize) { sigaddset (&signal_set, SIGHUP); } struct sigaction act; act.sa_handler = copyexec_results_sig_handler; act.sa_mask = signal_set; act.sa_flags = 0; for (i = 1; i <= SIGRTMAX; i++) { if (sigismember (&signal_set, i)) { if (sigaction (i, &act, NULL) < 0) { kprintf ("sigaction (%d) failed. %m\n", i); exit (1); } } } for (i = 0; ; i++) { if (!(i & 255)) { vkprintf (1, "epoll_work(): %d out of %d connections, network buffers: %d used, %d out of %d allocated\n", active_connections, maxconn, NB_used, NB_alloc, NB_max); } epoll_work (71); if (interrupted_by_term_signal ()) { break; } if (pending_signals & (1LL << SIGHUP)) { pending_signals_clear_bit (&signal_set, SIGHUP); kprintf ("got SIGHUP.\n"); sync_binlog (2); } if (pending_signals & (1LL << SIGUSR1)) { pending_signals_clear_bit (&signal_set, SIGUSR1); kprintf ("got SIGUSR1, rotate logs.\n"); reopen_logs (); sync_binlog (2); } if (now != prev_time) { prev_time = now; cron (); } if (quit_steps && !--quit_steps) break; } epoll_close (sfd); close (sfd); flush_binlog_last (); sync_binlog (2); }