0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-15 07:38:43 +00:00

Coro: Fixed deadlock when CLI is killed.

This commit is contained in:
Jan Maria Matejka 2018-08-28 16:45:07 +02:00
parent 7bea21ac84
commit 4600e95fe4
4 changed files with 24 additions and 9 deletions

View File

@ -18,5 +18,6 @@ void coro_resume(coroutine *c);
struct birdsock; struct birdsock;
int coro_sk_read(struct birdsock *s); int coro_sk_read(struct birdsock *s);
void coro_sk_write(struct birdsock *s, unsigned len);
#endif #endif

View File

@ -83,6 +83,7 @@ typedef struct birdsock {
struct ssh_sock *ssh; /* Used in SK_SSH */ struct ssh_sock *ssh; /* Used in SK_SSH */
struct coroutine *rx_coroutine; struct coroutine *rx_coroutine;
struct coroutine *tx_coroutine;
} sock; } sock;
sock *sock_new(pool *); /* Allocate new socket */ sock *sock_new(pool *); /* Allocate new socket */

View File

@ -245,8 +245,7 @@ cli_write(cli *c)
s->tbuf = o->outpos; s->tbuf = o->outpos;
o->outpos = o->wpos; o->outpos = o->wpos;
if (sk_send(s, len) <= 0) coro_sk_write(s, len);
return;
c->tx_pos = o->next; c->tx_pos = o->next;
} }
@ -264,12 +263,6 @@ cli_write_trigger(cli *c)
cli_write(c); cli_write(c);
} }
static void
cli_tx_hook(sock *s)
{
cli_write(s->data);
}
static void static void
cli_err_hook(sock *s, int err) cli_err_hook(sock *s, int err)
{ {
@ -540,7 +533,6 @@ cli_new(sock *s)
s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */ s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */
rmove(s, c->pool); rmove(s, c->pool);
s->tx_hook = cli_tx_hook;
s->err_hook = cli_err_hook; s->err_hook = cli_err_hook;
s->data = c; s->data = c;

View File

@ -146,6 +146,7 @@ static void
coro_free(resource *r) coro_free(resource *r)
{ {
coroutine *c = (coroutine *) r; coroutine *c = (coroutine *) r;
ASSERT(coro_current != c);
pthread_cancel(c->thread); pthread_cancel(c->thread);
pthread_join(c->thread, NULL); pthread_join(c->thread, NULL);
} }
@ -246,6 +247,14 @@ coro_sk_rx_hook(sock *sk, uint size UNUSED)
return 0; return 0;
} }
static void
coro_sk_tx_hook(sock *sk)
{
ASSERT(sk->tx_coroutine);
ASSERT(!coro_current);
coro_resume(sk->tx_coroutine);
}
int int
coro_sk_read(sock *s) coro_sk_read(sock *s)
{ {
@ -256,3 +265,15 @@ coro_sk_read(sock *s)
s->rx_hook = NULL; s->rx_hook = NULL;
return s->rpos - s->rbuf; return s->rpos - s->rbuf;
} }
void
coro_sk_write(sock *s, unsigned len)
{
ASSERT(coro_current);
s->tx_coroutine = coro_current;
s->tx_hook = coro_sk_tx_hook;
s->ttx = s->tbuf;
s->tpos = s->tbuf + len;
coro_suspend();
s->tx_hook = NULL;
}