{"action":"created","issue":{"url":"https://api.github.com/repos/eventmachine/eventmachine/issues/522","labels_url":"https://api.github.com/repos/eventmachine/eventmachine/issues/522/labels{/name}","comments_url":"https://api.github.com/repos/eventmachine/eventmachine/issues/522/comments","events_url":"https://api.github.com/repos/eventmachine/eventmachine/issues/522/events","html_url":"https://github.com/eventmachine/eventmachine/issues/522","id":37535399,"number":522,"title":"When using epoll, `stop_event_loop` doesn't take effect until the next timer fires","user":{"login":"piki","id":3660033,"avatar_url":"https://avatars.githubusercontent.com/u/3660033?v=3","gravatar_id":"","url":"https://api.github.com/users/piki","html_url":"https://github.com/piki","followers_url":"https://api.github.com/users/piki/followers","following_url":"https://api.github.com/users/piki/following{/other_user}","gists_url":"https://api.github.com/users/piki/gists{/gist_id}","starred_url":"https://api.github.com/users/piki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piki/subscriptions","organizations_url":"https://api.github.com/users/piki/orgs","repos_url":"https://api.github.com/users/piki/repos","events_url":"https://api.github.com/users/piki/events{/privacy}","received_events_url":"https://api.github.com/users/piki/received_events","type":"User","site_admin":true},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2014-07-10T06:33:51Z","updated_at":"2015-02-07T07:38:06Z","closed_at":null,"body":"When eventmachine is using `EM.epoll` and has at least one timer set up, a call to `stop_event_loop` will have no effect until the next timer fires.\r\n\r\nFor example, this program takes up to five seconds to exit when it gets a SIGTERM.  If there aren't any timers, the program exits after about 90ms, the value of `Quantum.tv_usec`.  If the `EM.epoll` line is commented out, the program exits immediately, whether or not any timers are scheduled.\r\n\r\n```\r\nEM.epoll\r\nEM.run {\r\n  EM.add_periodic_timer(5) do\r\n    puts \"timer\"\r\n  end\r\n  EM.add_shutdown_hook do\r\n    puts \"shutting down: #{Time.now.to_f}\"\r\n  end\r\n  Signal.trap(\"TERM\") do\r\n    puts \"SIGTERM: #{Time.now.to_f}\"\r\n    EM::stop_event_loop\r\n  end\r\n}\r\n```\r\n\r\nDoes the epoll version of `stop` need to signal the loop breaker?"},"comment":{"url":"https://api.github.com/repos/eventmachine/eventmachine/issues/comments/73354137","html_url":"https://github.com/eventmachine/eventmachine/issues/522#issuecomment-73354137","issue_url":"https://api.github.com/repos/eventmachine/eventmachine/issues/522","id":73354137,"user":{"login":"piki","id":3660033,"avatar_url":"https://avatars.githubusercontent.com/u/3660033?v=3","gravatar_id":"","url":"https://api.github.com/users/piki","html_url":"https://github.com/piki","followers_url":"https://api.github.com/users/piki/followers","following_url":"https://api.github.com/users/piki/following{/other_user}","gists_url":"https://api.github.com/users/piki/gists{/gist_id}","starred_url":"https://api.github.com/users/piki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piki/subscriptions","organizations_url":"https://api.github.com/users/piki/orgs","repos_url":"https://api.github.com/users/piki/repos","events_url":"https://api.github.com/users/piki/events{/privacy}","received_events_url":"https://api.github.com/users/piki/received_events","type":"User","site_admin":true},"created_at":"2015-02-07T07:38:06Z","updated_at":"2015-02-07T07:38:06Z","body":"There may be an easier way to fix this that doesn't involve the loop breaker.  (The loop breaker may be worth avoiding, because it calls Ruby callbacks rather than just stopping EM.)\r\n\r\nThe underlying problem is that `rb_wait_for_single_fd` (used [here](https://github.com/eventmachine/eventmachine/blob/master/ext/em.cpp#L577)) retries its `ppoll` call on any `EINTR`.  So the process gets SIGTERM or SIGINT, calls `EM.stop`, sets `bTerminateSignalReceived`, and then retries `ppoll` with the original timeout anyway.  If we skip the `rb_wait_for_single_fd` call and just go straight to `epoll_wait` -- which doesn't retry after `EINTR` -- everything appears to work.  It's as simple as removing the entire `#ifdef BUILD_FOR_RUBY` block [here](https://github.com/eventmachine/eventmachine/blob/master/ext/em.cpp#L573-L601).\r\n\r\n@tmm1, it appears you wrote the `BUILD_FOR_RUBY` block.  I'm not sure what that `#define` means.  What's [the block](https://github.com/eventmachine/eventmachine/blob/master/ext/em.cpp#L573-L601) there for, and can we just remove it?"}}