X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Fchannel.c;h=5487d051b5013fd60b080491ce865966bc6ffeab;hp=5214fe73a41eeae6d96985e16fece47d45f1d7f8;hb=f83bcd90ceb5ce659ffe9d7747d6f3366a09748a;hpb=03732c3281c0cfbfd5f1a6b7723c577cab43bab3 diff --git a/src/lib/lttng-ctl/channel.c b/src/lib/lttng-ctl/channel.c index 5214fe73a..5487d051b 100644 --- a/src/lib/lttng-ctl/channel.c +++ b/src/lib/lttng-ctl/channel.c @@ -211,6 +211,7 @@ lttng_notification_channel_get_next_notification( struct lttng_notification *notification = NULL; enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; + fd_set read_fds; if (!channel || !_notification) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; @@ -239,6 +240,28 @@ lttng_notification_channel_get_next_notification( goto end_unlock; } + /* + * Block on select() instead of the message reception itself as the + * recvmsg() wrappers always restard on EINTR. We choose to wait + * using select() in order to: + * 1) Return if a signal occurs, + * 2) Not deal with partially received messages. + * + * The drawback to this approach is that we assume that messages + * are complete/well formed. If a message is shorter than its + * announced length, receive_message() will block on recvmsg() + * and never return (even if a signal is received). + */ + FD_ZERO(&read_fds); + FD_SET(channel->socket, &read_fds); + ret = select(channel->socket + 1, &read_fds, NULL, NULL, NULL); + if (ret == -1) { + status = errno == EINTR ? + LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED : + LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; + goto end_unlock; + } + ret = receive_message(channel); if (ret) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR;