From 6b301bd735bbbe384057a463ede871616efb5861 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 29 Apr 2014 07:37:40 +0200 Subject: [PATCH] Moved main server loop into its own function --- src/server.c | 134 +++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/src/server.c b/src/server.c index 44f262c..827b99b 100644 --- a/src/server.c +++ b/src/server.c @@ -92,14 +92,74 @@ struct sockaddr_storage** Server_setupAddressesAndPorts() return addresses; } +void Server_runLoop(struct pollfd* pollfds) + { + int timeout = 1000, rc, clientcount; + etimer_t janitorTimer; + + Timer_init(&janitorTimer); + + while (!shutdown_server) { + struct sockaddr_in remote; + int i; + + pollfds[UDP_SOCK].revents = 0; + pollfds[TCP_SOCK].revents = 0; + clientcount = Client_getfds(&pollfds[2]); + + timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL; + if (timeout <= 0) { + Client_janitor(); + Timer_restart(&janitorTimer); + timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL; + } + rc = poll(pollfds, clientcount + 2, timeout); + if (rc == 0) { /* Timeout */ + /* Do maintenance */ + Timer_restart(&janitorTimer); + Client_janitor(); + continue; + } + if (rc < 0) { + if (errno == EINTR) /* signal */ + continue; + else + Log_fatal("poll: error %d", errno); + } + if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */ + int tcpfd, flag = 1; + uint32_t addrlen; + addrlen = sizeof(struct sockaddr_in); + tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen); + fcntl(tcpfd, F_SETFL, O_NONBLOCK); + setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + Log_debug("Connection from %s port %d\n", inet_ntoa(remote.sin_addr), + ntohs(remote.sin_port)); + if (Client_add(tcpfd, &remote) < 0) + close(tcpfd); + } + + if (pollfds[UDP_SOCK].revents) { + Client_read_udp(); + } + for (i = 0; i < clientcount; i++) { + if (pollfds[i + 2].revents & POLLIN) { + Client_read_fd(pollfds[i + 2].fd); + } + if (pollfds[i + 2].revents & POLLOUT) { + Client_write_fd(pollfds[i + 2].fd); + } + } + } + } + void Server_run() { - int timeout = 1000, rc; + int rc; struct pollfd *pollfds; int tcpsock, sockopt = 1; struct sockaddr_in sin; - int val, clientcount; - etimer_t janitorTimer; + int val; unsigned short port; in_addr_t inet_address; @@ -109,18 +169,7 @@ void Server_run() Log_fatal("out of memory"); /* Figure out bind address and port */ - if (bindport != 0) - port = htons(bindport); - else - port = htons(getIntConf(BINDPORT)); - - if (bindaddr != NULL && inet_addr(bindaddr) != -1) - inet_address = inet_addr(bindaddr); - else if (inet_addr(getStrConf(BINDADDR)) != -1) - inet_address = inet_addr(getStrConf(BINDADDR)); - else - inet_address = inet_addr("0.0.0.0"); - Log_info("Bind to %s:%hu", inet_address == 0 ? "*" : inet_ntoa(*((struct in_addr *)&inet_address)), ntohs(port)); + struct sockaddr_storage** addresses = Server_setupAddressesAndPorts(); /* Prepare TCP socket */ memset(&sin, 0, sizeof(sin)); @@ -165,65 +214,12 @@ void Server_run() pollfds[UDP_SOCK].fd = udpsock; pollfds[UDP_SOCK].events = POLLIN | POLLHUP | POLLERR; - Timer_init(&janitorTimer); - Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d", UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH); Log_info("Visit http://code.google.com/p/umurmur/"); /* Main server loop */ - while (!shutdown_server) { - struct sockaddr_in remote; - int i; - - pollfds[UDP_SOCK].revents = 0; - pollfds[TCP_SOCK].revents = 0; - clientcount = Client_getfds(&pollfds[2]); - - timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL; - if (timeout <= 0) { - Client_janitor(); - Timer_restart(&janitorTimer); - timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL; - } - rc = poll(pollfds, clientcount + 2, timeout); - if (rc == 0) { /* Timeout */ - /* Do maintenance */ - Timer_restart(&janitorTimer); - Client_janitor(); - continue; - } - if (rc < 0) { - if (errno == EINTR) /* signal */ - continue; - else - Log_fatal("poll: error %d", errno); - } - if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */ - int tcpfd, flag = 1; - uint32_t addrlen; - addrlen = sizeof(struct sockaddr_in); - tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen); - fcntl(tcpfd, F_SETFL, O_NONBLOCK); - setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); - Log_debug("Connection from %s port %d\n", inet_ntoa(remote.sin_addr), - ntohs(remote.sin_port)); - if (Client_add(tcpfd, &remote) < 0) - close(tcpfd); - } - - if (pollfds[UDP_SOCK].revents) { - Client_read_udp(); - } - for (i = 0; i < clientcount; i++) { - if (pollfds[i + 2].revents & POLLIN) { - Client_read_fd(pollfds[i + 2].fd); - } - if (pollfds[i + 2].revents & POLLOUT) { - Client_write_fd(pollfds[i + 2].fd); - } - } - } + Server_runLoop(pollfds); /* Disconnect clients */ Client_disconnect_all(); -- 2.30.2