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:
parent
4b4fe1bd65
commit
6768e0cf9e
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user