Beispiel #1
0
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;
}
Beispiel #2
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();
}
Beispiel #3
0
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");
  }
}
Beispiel #5
0
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, &copyexec_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);
}