From: Sage Weil Date: Wed, 24 Jul 2013 04:27:50 +0000 (-0700) Subject: global/signal_handler: use poll(2) instead of select(2) X-Git-Tag: v0.67-rc2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8e4a78f169eda716c7d6811cb6db5c757dc67207;p=ceph.git global/signal_handler: use poll(2) instead of select(2) Starting with commit 61a298c39c1a6684682e2b749e45a66d073182c8 we delay the signal handler setup until after lots of other initialization has happened, which can result in us having very large (>1024) open fds, which will break the FD_SET macros for select(2). Use poll(2) instead. Fixes: #5722 Signed-off-by: Sage Weil Reviewed-by: Yehuda Sadeh --- diff --git a/src/global/signal_handler.cc b/src/global/signal_handler.cc index 25f1a0a19929..d403637002b1 100644 --- a/src/global/signal_handler.cc +++ b/src/global/signal_handler.cc @@ -19,6 +19,7 @@ #include "global/pidfile.h" #include "global/signal_handler.h" +#include #include #include #include @@ -189,25 +190,23 @@ struct SignalHandler : public Thread { // thread entry point void *entry() { while (!stop) { - // create fd set - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(pipefd[0], &rfds); - int max_fd = pipefd[0]; + // build fd list + struct pollfd fds[33]; lock.Lock(); + int num_fds = 0; for (unsigned i=0; i<32; i++) { if (handlers[i]) { - int fd = handlers[i]->pipefd[0]; - FD_SET(fd, &rfds); - if (fd > max_fd) - max_fd = fd; + fds[num_fds].fd = handlers[i]->pipefd[0]; + fds[num_fds].events = POLLIN | POLLOUT | POLLERR; + fds[num_fds].revents = 0; + ++num_fds; } } lock.Unlock(); // wait for data on any of those pipes - int r = select(max_fd + 1, &rfds, NULL, NULL, NULL); + int r = poll(fds, num_fds, -1); if (stop) break; if (r > 0) { diff --git a/src/test/signals.cc b/src/test/signals.cc index 437549885599..2c7f4d32a0af 100644 --- a/src/test/signals.cc +++ b/src/test/signals.cc @@ -110,3 +110,33 @@ TEST(SignalHandler, Multiple) unregister_async_signal_handler(SIGUSR2, testhandler); shutdown_async_signal_handler(); } + +/* +TEST(SignalHandler, MultipleBigFd) +{ + int ret; + + for (int i = 0; i < 1500; i++) + ::open(".", O_RDONLY); + + reset(); + init_async_signal_handler(); + register_async_signal_handler(SIGUSR1, testhandler); + register_async_signal_handler(SIGUSR2, testhandler); + ASSERT_TRUE(usr1 == false); + ASSERT_TRUE(usr2 == false); + + ret = kill(getpid(), SIGUSR1); + ASSERT_EQ(ret, 0); + ret = kill(getpid(), SIGUSR2); + ASSERT_EQ(ret, 0); + + sleep(1); + ASSERT_TRUE(usr1 == true); + ASSERT_TRUE(usr2 == true); + + unregister_async_signal_handler(SIGUSR1, testhandler); + unregister_async_signal_handler(SIGUSR2, testhandler); + shutdown_async_signal_handler(); +} +*/