Skip to content

Instantly share code, notes, and snippets.

@sortie
Created January 14, 2016 15:15
Show Gist options
  • Save sortie/6bd7f75d1dced7514a4a to your computer and use it in GitHub Desktop.
Save sortie/6bd7f75d1dced7514a4a to your computer and use it in GitHub Desktop.
server main loop
int main(void)
{
signal(SIGPIPE, SIG_IGN );
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* servinfo;
int status = getaddrinfo(NULL, "5742", &hints, &servinfo);
if ( status )
errx(1, "getaddrinfo: %s", gai_strerror(status));
int server_fd = socket(servinfo->ai_family, servinfo->ai_socktype,
servinfo->ai_protocol);
if ( server_fd < 0 )
err(1, "socket");
int reuseaddr = 1;
if ( setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
sizeof(reuseaddr)) < 0 )
err(1, "setsockopt: SO_REUSEADDR");
if ( bind(server_fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0 )
err(1, "bind");
freeaddrinfo(servinfo);
if ( listen(server_fd, 5) < 0 )
err(1, "listen");
memset(connections, 0, sizeof(connections));
for ( size_t i = 0; i < MAX_CONNECTIONS; i++ )
connections[i].fd = -1;
printf("online\n");
while ( true )
{
nfds_t nfds = 1 + MAX_CONNECTIONS;
struct pollfd pfds[nfds];
memset(pfds, 0, sizeof(pfds));
for ( nfds_t i = 0; i < nfds; i++ )
pfds[i].fd = -1;
if ( num_connections != MAX_CONNECTIONS )
{
pfds[0].fd = server_fd;
pfds[0].events = POLLIN;
}
bool timeout_set = false;
struct timespec timeout;
for ( size_t i = 0; i < MAX_CONNECTIONS; i++ )
{
if ( connections[i].fd == -1 )
continue;
struct timespec conn_timeout;
bool conn_timeout_set = false;
short events = connection_events(&connections[i], &conn_timeout,
&conn_timeout_set);
pfds[1 + i].fd = connections[i].fd;
pfds[1 + i].events = events;
if ( conn_timeout_set )
{
if ( timeout_set && timespec_lt(timeout, conn_timeout) )
timeout = conn_timeout;
else if ( !timeout_set )
{
timeout = conn_timeout;
timeout_set = true;
}
}
}
if ( ppoll(pfds, nfds, timeout_set ? &timeout : NULL, NULL) < 0 )
{
warn("poll");
continue;
}
if ( pfds[0].revents )
connection_accept(server_fd);
for ( size_t i = 0; i < MAX_CONNECTIONS; i++ )
{
if ( connections[i].fd == -1 )
continue;
if ( pfds[1 + i].revents & (POLLERR | POLLHUP | POLLNVAL) )
{
connection_close(&connections[i]);
continue;
}
if ( connections[i].fd != -1 && pfds[1 + i].revents & POLLIN )
connection_incoming(&connections[i]);
if ( connections[i].fd != -1 && pfds[1 + i].revents & POLLOUT )
connection_outgoing(&connections[i]);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment