Skip to content

Commit

Permalink
fix epoll thread blocking issue by calling rb_thread_select on the ep…
Browse files Browse the repository at this point in the history
…oll fd
  • Loading branch information
jakedouglas committed Nov 23, 2009
1 parent 0319eb8 commit d684cc3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
55 changes: 46 additions & 9 deletions ext/em.cpp
Expand Up @@ -514,12 +514,28 @@ bool EventMachine_t::_RunEpollOnce()
assert (epfd != -1);
int s;

timeval tv = _TimeTilNextEvent();

#ifdef BUILD_FOR_RUBY
int ret = 0;
fd_set fdreads;

FD_ZERO(&fdreads);
FD_SET(epfd, &fdreads);

while ((ret = rb_thread_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
if (ret == -1) continue;
if (ret == 0) return true;
}

TRAP_BEG;
#endif
s = epoll_wait (epfd, epoll_events, MaxEvents, 50);
#ifdef BUILD_FOR_RUBY
s = epoll_wait (epfd, epoll_events, MaxEvents, 0);
TRAP_END;
#else
int duration = 0;
duration = duration + (tv.tv_sec * 1000);
duration = duration + (tv.tv_usec / 1000);
s = epoll_wait (epfd, epoll_events, MaxEvents, duration);
#endif

if (s > 0) {
Expand Down Expand Up @@ -548,12 +564,6 @@ bool EventMachine_t::_RunEpollOnce()
EmSelect (0, NULL, NULL, NULL, &tv);
}

#ifdef BUILD_FOR_RUBY
if (!rb_thread_alone()) {
rb_thread_schedule();
}
#endif

return true;
#else
throw std::runtime_error ("epoll is not implemented on this platform");
Expand Down Expand Up @@ -628,6 +638,33 @@ bool EventMachine_t::_RunKqueueOnce()
}


/*********************************
EventMachine_t::_TimeTilNextEvent
*********************************/

timeval EventMachine_t::_TimeTilNextEvent()
{
multimap<uint64_t,EventableDescriptor*>::iterator heartbeats = Heartbeats.begin();
multimap<uint64_t,Timer_t>::iterator timers = Timers.begin();

uint64_t next_event = heartbeats->first;

if (timers->first != 0 && timers->first < next_event)
next_event = timers->first;

timeval tv;

if (next_event == 0) {
tv = Quantum;
} else {
uint64_t duration = next_event - MyCurrentLoopTime;
tv.tv_sec = duration / 1000000;
tv.tv_usec = duration % 1000000;
}

return tv;
}

/*******************************
EventMachine_t::_CleanupSockets
*******************************/
Expand Down
1 change: 1 addition & 0 deletions ext/em.h
Expand Up @@ -156,6 +156,7 @@ class EventMachine_t

void _ModifyEpollEvent (EventableDescriptor*);
void _DispatchHeartbeats();
timeval _TimeTilNextEvent();

public:
void _ReadLoopBreaker();
Expand Down

0 comments on commit d684cc3

Please sign in to comment.