Switch from sketchy dup() juggling to callbacks to retry outgoing connection.
This commit is contained in:
@@ -17,41 +17,41 @@
|
||||
#include "peer.h"
|
||||
|
||||
static int peer_epoll_fd;
|
||||
static int peer_cancel_fd;
|
||||
static bool peer_canceled = false;
|
||||
static int peer_shutdown_fd;
|
||||
static bool peer_shutdown_flag = false;
|
||||
|
||||
static void peer_cancel(int signal) {
|
||||
assert(!close(peer_cancel_fd));
|
||||
}
|
||||
|
||||
static void peer_cancel_handler(struct peer *peer) {
|
||||
static void peer_shutdown_handler(struct peer *peer) {
|
||||
fprintf(stderr, "X %s: Shutting down\n", server_id);
|
||||
assert(!close(peer->fd));
|
||||
free(peer);
|
||||
peer_canceled = true;
|
||||
peer_shutdown_flag = true;
|
||||
}
|
||||
|
||||
void peer_init() {
|
||||
peer_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||
assert(peer_epoll_fd >= 0);
|
||||
|
||||
int cancel_fds[2];
|
||||
assert(!pipe2(cancel_fds, O_CLOEXEC));
|
||||
int shutdown_fds[2];
|
||||
assert(!pipe2(shutdown_fds, O_CLOEXEC));
|
||||
|
||||
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);
|
||||
struct peer *shutdown_peer = malloc(sizeof(*shutdown_peer));
|
||||
assert(shutdown_peer);
|
||||
shutdown_peer->fd = shutdown_fds[0];
|
||||
shutdown_peer->event_handler = peer_shutdown_handler;
|
||||
peer_epoll_add(shutdown_peer, EPOLLRDHUP);
|
||||
|
||||
peer_cancel_fd = cancel_fds[1];
|
||||
signal(SIGINT, peer_cancel);
|
||||
peer_shutdown_fd = shutdown_fds[1];
|
||||
signal(SIGINT, peer_shutdown);
|
||||
}
|
||||
|
||||
void peer_cleanup() {
|
||||
assert(!close(peer_epoll_fd));
|
||||
}
|
||||
|
||||
void peer_shutdown(int signal) {
|
||||
assert(!close(peer_shutdown_fd));
|
||||
}
|
||||
|
||||
void peer_epoll_add(struct peer *peer, uint32_t events) {
|
||||
struct epoll_event ev = {
|
||||
.events = events,
|
||||
@@ -66,9 +66,16 @@ void peer_epoll_del(struct peer *peer) {
|
||||
assert(!epoll_ctl(peer_epoll_fd, EPOLL_CTL_DEL, peer->fd, NULL));
|
||||
}
|
||||
|
||||
void peer_call(struct peer *peer) {
|
||||
if (peer_shutdown_flag || !peer) {
|
||||
return;
|
||||
}
|
||||
peer->event_handler(peer);
|
||||
}
|
||||
|
||||
void peer_loop() {
|
||||
fprintf(stderr, "X %s: Starting event loop\n", server_id);
|
||||
while (!peer_canceled) {
|
||||
while (!peer_shutdown_flag) {
|
||||
#define MAX_EVENTS 10
|
||||
struct epoll_event events[MAX_EVENTS];
|
||||
int nfds = epoll_wait(peer_epoll_fd, events, MAX_EVENTS, wakeup_get_delay());
|
||||
|
||||
Reference in New Issue
Block a user