LOOP: move pipe creation into qb_loop_signals_create()

Also make sure the pipe is non blocking.

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2010-11-16 14:38:34 +11:00
parent 3d7f619968
commit 668eb0a2d5
4 changed files with 93 additions and 74 deletions

View File

@ -73,43 +73,6 @@ static void socket_nosigpipe(int32_t s)
}
#endif
static int32_t set_cloexec_flag(int32_t fd)
{
int32_t res;
char error_str[100];
int32_t oldflags = fcntl(fd, F_GETFD, 0);
if (oldflags < 0) {
oldflags = 0;
}
oldflags |= FD_CLOEXEC;
res = fcntl(fd, F_SETFD, oldflags);
if (res == -1) {
res = -errno;
strerror_r(errno, error_str, 100);
qb_util_log(LOG_CRIT,
"Could not set close-on-exit operation on socket: %s\n",
error_str);
}
return res;
}
static int32_t set_nonblock_flag(int32_t fd)
{
int32_t res;
char error_str[100];
res = fcntl(fd, F_SETFL, O_NONBLOCK);
if (res == -1) {
res = -errno;
strerror_r(errno, error_str, 100);
qb_util_log(LOG_CRIT,
"Could not set non-blocking operation on socket: %s\n",
error_str);
}
return res;
}
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
@ -302,11 +265,7 @@ static int32_t qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_p
#ifdef SO_NOSIGPIPE
socket_nosigpipe(request_fd);
#endif /* SO_NOSIGPIPE */
res = set_cloexec_flag(request_fd);
if (res < 0) {
goto error_connect;
}
res = set_nonblock_flag(request_fd);
res = qb_util_fd_nonblock_cloexec_set(request_fd);
if (res < 0) {
goto error_connect;
}
@ -481,11 +440,7 @@ int32_t qb_ipcs_us_publish(struct qb_ipcs_service * s)
return res;
}
res = set_cloexec_flag(s->server_sock);
if (res < 0) {
goto error_close;
}
res = set_nonblock_flag(s->server_sock);
res = qb_util_fd_nonblock_cloexec_set(s->server_sock);
if (res < 0) {
goto error_close;
}
@ -816,12 +771,7 @@ retry_accept:
return 0; /* This is an error, but -1 would indicate disconnect from poll loop */
}
res = set_cloexec_flag(new_fd);
if (res < 0) {
close(new_fd);
return 0; /* This is an error, but -1 would indicate disconnect from poll loop */
}
res = set_nonblock_flag(new_fd);
res = qb_util_fd_nonblock_cloexec_set(new_fd);
if (res < 0) {
close(new_fd);
return 0; /* This is an error, but -1 would indicate disconnect from poll loop */

View File

@ -95,6 +95,8 @@ struct qb_poll_source {
int32_t not_enough_fds;
};
static int32_t _qb_signal_add_to_jobs_(struct qb_loop* l,
struct qb_poll_entry* pe);
#ifdef HAVE_EPOLL
static int32_t poll_to_epoll_event(int32_t event)
@ -741,8 +743,17 @@ struct qb_loop_sig {
static void _handle_real_signal_(int signal_num, siginfo_t * si, void *context)
{
int32_t sig = signal_num;
int32_t res = 0;
if (pipe_fds[1] > 0) {
(void)write(pipe_fds[1], &sig, sizeof(int32_t));
try_again:
res = write(pipe_fds[1], &sig, sizeof(int32_t));
if (res == -1 && errno == EAGAIN) {
goto try_again;
} else if (res != sizeof(int32_t)) {
qb_util_log(LOG_ERR, "failed to write signal to pipe [%d]",
res);
}
}
}
@ -764,14 +775,49 @@ static void signal_dispatch_and_take_back(struct qb_loop_item * item,
struct qb_loop_source *
qb_loop_signals_create(struct qb_loop *l)
{
int32_t res = 0;
struct qb_poll_entry *pe;
struct qb_signal_source *s = calloc(1, sizeof(struct qb_signal_source));
s->s.l = l;
s->s.dispatch_and_take_back = signal_dispatch_and_take_back;
s->s.poll = NULL;
qb_list_init(&s->sig_head);
sigemptyset(&s->signal_superset);
if (pipe_fds[0] < 0) {
res = pipe(pipe_fds);
if (res == -1) {
res = -errno;
qb_util_log(LOG_ERR,
"Can't light pipe: %s",
strerror(-res));
goto error_exit;
}
(void)qb_util_fd_nonblock_cloexec_set(pipe_fds[0]);
(void)qb_util_fd_nonblock_cloexec_set(pipe_fds[1]);
res = _poll_add_(l, QB_LOOP_HIGH,
pipe_fds[0], POLLIN,
NULL, &pe);
if (res == 0) {
pe->poll_dispatch_fn = NULL;
pe->type = QB_SIGNAL;
pe->add_to_jobs = _qb_signal_add_to_jobs_;
} else {
qb_util_log(LOG_ERR,
"Can't smoke pipe: %s",
strerror(-res));
goto error_exit;
}
}
return (struct qb_loop_source *)s;
error_exit:
free(s);
errno = -res;
return NULL;
}
void qb_loop_signals_destroy(struct qb_loop *l)
@ -860,9 +906,7 @@ int32_t qb_loop_signal_add(qb_loop_t *l,
qb_loop_signal_handle *handle)
{
struct qb_loop_sig *sig;
struct qb_poll_entry *pe;
struct qb_signal_source *s;
int32_t res = 0;
if (l == NULL || dispatch_fn == NULL) {
return -EINVAL;
@ -882,22 +926,6 @@ int32_t qb_loop_signal_add(qb_loop_t *l,
qb_list_init(&sig->item.list);
qb_list_add_tail(&sig->item.list, &s->sig_head);
if (pipe_fds[0] < 0) {
pipe(pipe_fds);
res = _poll_add_(l, QB_LOOP_HIGH,
pipe_fds[0], POLLIN,
NULL, &pe);
if (res == 0) {
pe->poll_dispatch_fn = NULL;
pe->type = QB_SIGNAL;
pe->add_to_jobs = _qb_signal_add_to_jobs_;
} else {
qb_util_log(LOG_ERR,
"failed to setup pipe: %s",
strerror(-res));
}
}
if (sigismember(&s->signal_superset, the_sig) != 1) {
_adjust_sigactions_(s);
}

View File

@ -353,3 +353,36 @@ int32_t qb_util_circular_mmap(int32_t fd, void **buf, size_t bytes)
*buf = addr_orig;
return (0);
}
int32_t qb_util_fd_nonblock_cloexec_set(int32_t fd)
{
int32_t res;
char error_str[100];
int32_t oldflags = fcntl(fd, F_GETFD, 0);
if (oldflags < 0) {
oldflags = 0;
}
oldflags |= FD_CLOEXEC;
res = fcntl(fd, F_SETFD, oldflags);
if (res == -1) {
res = -errno;
strerror_r(errno, error_str, 100);
qb_util_log(LOG_CRIT,
"Could not set close-on-exit operation on fd: %s\n",
error_str);
return res;
}
res = fcntl(fd, F_SETFL, O_NONBLOCK);
if (res == -1) {
res = -errno;
strerror_r(errno, error_str, 100);
qb_util_log(LOG_CRIT,
"Could not set non-blocking operation on fd: %s\n",
error_str);
}
return res;
}

View File

@ -40,7 +40,7 @@ void _qb_util_log(const char *file_name,
* @param file (in) the name of the file to be used.
* @param bytes the size to truncate the file to.
* @param file_flags same as passed into open()
* @return 0 (success) or -1 (error)
* @return 0 (success) or -errno
*/
int32_t qb_util_mmap_file_open(char *path, const char *file, size_t bytes,
uint32_t file_flags);
@ -51,8 +51,16 @@ int32_t qb_util_mmap_file_open(char *path, const char *file, size_t bytes,
* @param fd an open file to use to back the shared memory.
* @param buf (out) the pointer to the start of the memory.
* @param bytes the size of the shared memory.
* @return 0 (success) or -1 (error)
* @return 0 (success) or -errno
*/
int32_t qb_util_circular_mmap(int32_t fd, void **buf, size_t bytes);
/**
* Set O_NONBLOCK and FD_CLOEXEC on a file descriptor.
* @param fd the file descriptor.
* @return 0 (success) or -errno
*/
int32_t qb_util_fd_nonblock_cloexec_set(int32_t fd);
#endif /* QB_UTIL_INT_H_DEFINED */