0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

Pipe kick-and-drain packed into a neat structure and functions.

This commit is contained in:
Maria Matejka 2022-09-20 17:01:50 +02:00
parent 4b4fe1bd65
commit 6768e0cf9e
4 changed files with 66 additions and 45 deletions

View File

@ -951,10 +951,6 @@ bfd_reconfigure_neighbors(struct bfd_proto *p, struct bfd_config *new)
/* This core notify code should be replaced after main loop transition to birdloop */ /* This core notify code should be replaced after main loop transition to birdloop */
int pipe(int pipefd[2]);
void pipe_drain(int fd);
void pipe_kick(int fd);
static void static void
bfd_notify_hook(void *data) bfd_notify_hook(void *data)
{ {

View File

@ -88,74 +88,94 @@ birdloop_process_flags(struct birdloop *loop)
* Wakeup code for birdloop * Wakeup code for birdloop
*/ */
static void void
pipe_new(int *pfds) pipe_new(struct pipe *p)
{ {
int rv = pipe(pfds); int rv = pipe(p->fd);
if (rv < 0) if (rv < 0)
die("pipe: %m"); die("pipe: %m");
if (fcntl(pfds[0], F_SETFL, O_NONBLOCK) < 0) if (fcntl(p->fd[0], F_SETFL, O_NONBLOCK) < 0)
die("fcntl(O_NONBLOCK): %m"); die("fcntl(O_NONBLOCK): %m");
if (fcntl(pfds[1], F_SETFL, O_NONBLOCK) < 0) if (fcntl(p->fd[1], F_SETFL, O_NONBLOCK) < 0)
die("fcntl(O_NONBLOCK): %m"); die("fcntl(O_NONBLOCK): %m");
} }
void void
pipe_drain(int fd) pipe_drain(struct pipe *p)
{ {
char buf[64]; while (1) {
int rv; char buf[64];
int rv = read(p->fd[0], buf, sizeof(buf));
try: if ((rv < 0) && (errno == EAGAIN))
rv = read(fd, buf, 64);
if (rv < 0)
{
if (errno == EINTR)
goto try;
if (errno == EAGAIN)
return; return;
die("wakeup read: %m");
if (rv == 0)
bug("wakeup read eof");
if ((rv < 0) && (errno != EINTR))
bug("wakeup read: %m");
}
}
int
pipe_read_one(struct pipe *p)
{
while (1) {
char v;
int rv = read(p->fd[0], &v, sizeof(v));
if (rv == 1)
return 1;
if ((rv < 0) && (errno == EAGAIN))
return 0;
if (rv > 1)
bug("wakeup read more bytes than expected: %d", rv);
if (rv == 0)
bug("wakeup read eof");
if (errno != EINTR)
bug("wakeup read: %m");
} }
if (rv == 64)
goto try;
} }
void void
pipe_kick(int fd) pipe_kick(struct pipe *p)
{ {
u64 v = 1; char v = 1;
int rv; int rv;
try: while (1) {
rv = write(fd, &v, sizeof(u64)); rv = write(p->fd[1], &v, sizeof(v));
if (rv < 0) if ((rv >= 0) || (errno == EAGAIN))
{
if (errno == EINTR)
goto try;
if (errno == EAGAIN)
return; return;
die("wakeup write: %m"); if (errno != EINTR)
bug("wakeup write: %m");
} }
} }
void
pipe_pollin(struct pipe *p, struct pollfd *pfd)
{
pfd->fd = p->fd[0];
pfd->events = POLLIN;
pfd->revents = 0;
}
static inline void static inline void
wakeup_init(struct birdloop *loop) wakeup_init(struct birdloop *loop)
{ {
pipe_new(loop->wakeup_fds); pipe_new(&loop->wakeup);
} }
static inline void static inline void
wakeup_drain(struct birdloop *loop) wakeup_drain(struct birdloop *loop)
{ {
pipe_drain(loop->wakeup_fds[0]); pipe_drain(&loop->wakeup);
} }
static inline void static inline void
wakeup_do_kick(struct birdloop *loop) wakeup_do_kick(struct birdloop *loop)
{ {
pipe_kick(loop->wakeup_fds[1]); pipe_kick(&loop->wakeup);
} }
static inline void static inline void
@ -284,9 +304,7 @@ sockets_prepare(struct birdloop *loop)
/* Add internal wakeup fd */ /* Add internal wakeup fd */
*psk = NULL; *psk = NULL;
pfd->fd = loop->wakeup_fds[0]; pipe_pollin(&loop->wakeup, pfd);
pfd->events = POLLIN;
pfd->revents = 0;
loop->poll_changed = 0; loop->poll_changed = 0;
} }

View File

@ -9,6 +9,16 @@
#include "lib/rcu.h" #include "lib/rcu.h"
struct pipe
{
int fd[2];
};
void pipe_new(struct pipe *);
void pipe_pollin(struct pipe *, struct pollfd *);
void pipe_drain(struct pipe *);
void pipe_kick(struct pipe *);
struct birdloop struct birdloop
{ {
pool *pool; pool *pool;
@ -25,7 +35,7 @@ struct birdloop
uint ping_pending; uint ping_pending;
_Atomic u32 ping_sent; _Atomic u32 ping_sent;
int wakeup_fds[2]; struct pipe wakeup;
pthread_t thread_id; pthread_t thread_id;
pthread_attr_t thread_attr; pthread_attr_t thread_attr;

View File

@ -2213,8 +2213,6 @@ static int short_loops = 0;
#define SHORT_LOOP_MAX 10 #define SHORT_LOOP_MAX 10
#define WORK_EVENTS_MAX 10 #define WORK_EVENTS_MAX 10
void pipe_drain(int fd);
void void
io_loop(void) io_loop(void)
{ {
@ -2246,8 +2244,7 @@ io_loop(void)
} }
/* A hack to reload main io_loop() when something has changed asynchronously. */ /* A hack to reload main io_loop() when something has changed asynchronously. */
pfd[0].fd = main_birdloop.wakeup_fds[0]; pipe_pollin(&main_birdloop.wakeup, &pfd[0]);
pfd[0].events = POLLIN;
nfds = 1; nfds = 1;
@ -2325,7 +2322,7 @@ io_loop(void)
if (pfd[0].revents & POLLIN) if (pfd[0].revents & POLLIN)
{ {
/* IO loop reload requested */ /* IO loop reload requested */
pipe_drain(main_birdloop.wakeup_fds[0]); pipe_drain(&main_birdloop.wakeup);
atomic_exchange_explicit(&main_birdloop.ping_sent, 0, memory_order_acq_rel); atomic_exchange_explicit(&main_birdloop.ping_sent, 0, memory_order_acq_rel);
continue; continue;
} }