mirror of
https://github.com/ceph/ceph
synced 2025-01-18 17:12:29 +00:00
global/signal_handler: use poll(2) instead of select(2)
Starting with commit 61a298c39c
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 <sage@inktank.com>
Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
This commit is contained in:
parent
4183b74b00
commit
8e4a78f169
@ -19,6 +19,7 @@
|
||||
#include "global/pidfile.h"
|
||||
#include "global/signal_handler.h"
|
||||
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user