Much closer to complete cleanup before exit.

This commit is contained in:
Ian Gulliver
2016-02-21 13:57:35 -08:00
parent 71413f97e5
commit ec79ba0da1
8 changed files with 130 additions and 31 deletions

View File

@@ -1,26 +1,52 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <uuid/uuid.h>
#include "common.h"
static int epoll_fd;
static char server_id[UUID_LEN];
static int peer_epoll_fd;
static int peer_cancel_fd;
static bool peer_canceled = false;
static void peer_cancel(int signal) {
assert(!close(peer_cancel_fd));
}
static void peer_cancel_handler(struct peer *peer) {
fprintf(stderr, "X %s: Shutting down\n", server_id);
assert(!close(peer->fd));
free(peer);
peer_canceled = true;
}
void peer_init() {
uuid_gen(server_id);
peer_epoll_fd = epoll_create1(0);
assert(peer_epoll_fd >= 0);
int cancel_fds[2];
assert(!pipe2(cancel_fds, O_NONBLOCK));
struct peer *cancel_peer = malloc(sizeof(*cancel_peer));
assert(cancel_peer);
cancel_peer->fd = cancel_fds[0];
cancel_peer->event_handler = peer_cancel_handler;
peer_epoll_add(cancel_peer, EPOLLRDHUP);
peer_cancel_fd = cancel_fds[1];
signal(SIGINT, peer_cancel);
epoll_fd = epoll_create1(0);
assert(epoll_fd >= 0);
}
void peer_epoll_add(struct peer *peer, uint32_t events) {
@@ -30,28 +56,30 @@ void peer_epoll_add(struct peer *peer, uint32_t events) {
.ptr = peer,
},
};
assert(!epoll_ctl(epoll_fd, EPOLL_CTL_ADD, peer->fd, &ev));
assert(!epoll_ctl(peer_epoll_fd, EPOLL_CTL_ADD, peer->fd, &ev));
}
void peer_epoll_del(struct peer *peer) {
assert(!epoll_ctl(epoll_fd, EPOLL_CTL_DEL, peer->fd, NULL));
assert(!epoll_ctl(peer_epoll_fd, EPOLL_CTL_DEL, peer->fd, NULL));
}
void peer_loop() {
fprintf(stderr, "X %s: Starting event loop\n", server_id);
while (!peer_canceled) {
#define MAX_EVENTS 10
struct epoll_event events[MAX_EVENTS];
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds < 0) {
perror("epoll_wait");
break;
int nfds = epoll_wait(peer_epoll_fd, events, MAX_EVENTS, -1);
if (nfds == -1 && errno == EINTR) {
continue;
}
assert(nfds > 0);
for (int n = 0; n < nfds; n++) {
struct peer *peer = events[n].data.ptr;
peer->event_handler(peer);
}
}
assert(!close(peer_epoll_fd));
}