diff --git a/ospfd/libevent_helpers.h b/ospfd/libevent_helpers.h new file mode 100644 index 0000000..46f743d --- /dev/null +++ ospfd/libevent_helpers.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008 Eygene Ryabinkin + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIBEVENT_HELPERS_H_ +#define _LIBEVENT_HELPERS_H_ + +#include +#include + +#include "log.h" +#include "ospfd.h" + +/* Inline functions */ + +/* + * A support function that processes libevent notification in the + * following way: + * - if we are ready to write, we will try to flush the queue; + * - if we are ready to read, we will read the input buffer and + * prepare variables 'n' and 'shut' accordingly. + * + * Such handling occurs at least 6 times within the OSPFD sources, + * so this inline function is just an alternative to the preprocessor + * macros. + * + * Function returns 0 if everything was handled and no further + * processing is needed; it returns EV_READ if the read processing + * was prepared to take place. + */ +static inline short +dispatch_read_write_event(short _event, struct imsgbuf *_ibuf, + ssize_t *_n, int *_shut) __attribute__((always_inline)); + +static inline short +dispatch_read_write_event(short event, struct imsgbuf *ibuf, + ssize_t *n, int *shut) +{ + static char errbuf[128]; + + /* + * We can have both EV_READ and EV_WRITE, since we can be + * subscribed to both event types. Handle write readiness + * first (flush the queue) and then handle reads. + */ + if ((event & ~(EV_WRITE|EV_READ))) { + snprintf(errbuf, sizeof(errbuf), + "unknown event 0x%hx", (unsigned short)event); + fatalx(errbuf); + } + + if ((event & EV_WRITE)) { + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + } + if ((event & EV_READ)) { + if ((*n = imsg_read(ibuf)) == -1) + fatal("imsg_read error"); + if (*n == 0) /* connection closed */ + *shut = 1; + return EV_READ; + } else { + return 0; + } + /* NOTREACHED */ +} + +#endif /* _LIBEVENT_HELPERS_H_ */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index be69cab..4e62d09 100644 --- ospfd/ospfd.c +++ ospfd/ospfd.c @@ -46,6 +46,7 @@ #include "control.h" #include "log.h" #include "rde.h" +#include "libevent_helpers.h" void main_sig_handler(int, short, void *); __dead void usage(void); @@ -355,21 +356,8 @@ main_dispatch_ospfe(int fd, short event, void *bula) ssize_t n; int shut = 0; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) @@ -434,21 +422,8 @@ main_dispatch_rde(int fd, short event, void *bula) ssize_t n; int count, shut = 0; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) diff --git a/ospfd/ospfe.c b/ospfd/ospfe.c index af7a406..d6a6aa9 100644 --- ospfd/ospfe.c +++ ospfd/ospfe.c @@ -42,6 +42,7 @@ #include "rde.h" #include "control.h" #include "log.h" +#include "libevent_helpers.h" void ospfe_sig_handler(int, short, void *); void ospfe_shutdown(void); @@ -257,23 +258,11 @@ ospfe_dispatch_main(int fd, short event, void *bula) struct iface *iface = NULL; struct kif *kif; struct auth_md md; - int n, link_ok, stub_changed, shut = 0; - - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + int link_ok, stub_changed, shut = 0; + ssize_t n; + + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) @@ -401,24 +390,12 @@ ospfe_dispatch_rde(int fd, short event, void *bula) struct lsa_entry *le; struct imsg imsg; struct abr_rtr ar; - int n, noack = 0, shut = 0; + int noack = 0, shut = 0; u_int16_t l, age; + ssize_t n; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) diff --git a/ospfd/rde.c b/ospfd/rde.c index 5dd0623..faa0c23 100644 --- ospfd/rde.c +++ ospfd/rde.c @@ -37,6 +37,7 @@ #include "ospfe.h" #include "log.h" #include "rde.h" +#include "libevent_helpers.h" void rde_sig_handler(int sig, short, void *); void rde_shutdown(void); @@ -239,21 +240,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) int r, state, self, shut = 0; u_int16_t l; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } clock_gettime(CLOCK_MONOTONIC, &tp); now = tp.tv_sec; @@ -584,21 +572,8 @@ rde_dispatch_parent(int fd, short event, void *bula) ssize_t n; int shut = 0; - switch (event) { - case EV_READ: - if ((n = imsg_read(ibuf)) == -1) - fatal("imsg_read error"); - if (n == 0) /* connection closed */ - shut = 1; - break; - case EV_WRITE: - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - imsg_event_add(ibuf); + if (dispatch_read_write_event(event, ibuf, &n, &shut) != EV_READ) return; - default: - fatalx("unknown event"); - } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1)