Skip to content

Commit

Permalink
Fix race condition in kqueue event system implementation (#2193)
Browse files Browse the repository at this point in the history
This fixes a race condition in the kqueue back-end. Previously, it was possible for an unsubscribed (i.e. ASIO_DISPOSABLE) to be sent as an event in between being disposed and being sent as an ASIO_DISPOSABLE event. This could cause an event that had been unsubscribed to receive a read or a write event immediately before a dispose event.
  • Loading branch information
SeanTAllen committed Aug 26, 2017
1 parent b77e697 commit 5f29a0f
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions src/libponyrt/asio/kqueue.c
Expand Up @@ -161,28 +161,43 @@ DECLARE_THREAD_FN(ponyint_asio_backend_dispatch)
switch(ep->filter)
{
case EVFILT_READ:
ev->readable = true;
pony_asio_event_send(ev, ASIO_READ, 0);
if(ev->flags & ASIO_READ)
{
ev->readable = true;
pony_asio_event_send(ev, ASIO_READ, 0);
}
break;

case EVFILT_WRITE:
if(ep->flags & EV_EOF)
{
ev->readable = true;
ev->writeable = true;
pony_asio_event_send(ev, ASIO_READ | ASIO_WRITE, 0);
if(ev->flags & (ASIO_READ | ASIO_WRITE))
{
ev->readable = true;
ev->writeable = true;
pony_asio_event_send(ev, ASIO_READ | ASIO_WRITE, 0);
}
} else {
ev->writeable = true;
pony_asio_event_send(ev, ASIO_WRITE, 0);
if(ev->flags & ASIO_WRITE)
{
ev->writeable = true;
pony_asio_event_send(ev, ASIO_WRITE, 0);
}
}
break;

case EVFILT_TIMER:
pony_asio_event_send(ev, ASIO_TIMER, 0);
if(ev->flags & ASIO_TIMER)
{
pony_asio_event_send(ev, ASIO_TIMER, 0);
}
break;

case EVFILT_SIGNAL:
pony_asio_event_send(ev, ASIO_SIGNAL, (uint32_t)ep->data);
if(ev->flags & ASIO_SIGNAL)
{
pony_asio_event_send(ev, ASIO_SIGNAL, (uint32_t)ep->data);
}
break;

default: {}
Expand Down

0 comments on commit 5f29a0f

Please sign in to comment.