struct ustcomm_ust_reply lur;
int shm_fd, wait_fd;
union ust_args args;
+ ssize_t len;
ust_lock();
|| lum->cmd == LTTNG_UST_CHANNEL
|| lum->cmd == LTTNG_UST_METADATA)
&& lur.ret_code == USTCOMM_OK) {
+ int sendret = 0;
+
/* we also need to send the file descriptors. */
ret = ustcomm_send_fds_unix_sock(sock,
&shm_fd, &shm_fd,
1, sizeof(int));
if (ret < 0) {
perror("send shm_fd");
- goto error;
+ sendret = ret;
}
+ /*
+ * The sessiond expects 2 file descriptors, even upon
+ * error.
+ */
ret = ustcomm_send_fds_unix_sock(sock,
&wait_fd, &wait_fd,
1, sizeof(int));
perror("send wait_fd");
goto error;
}
+ if (sendret) {
+ ret = sendret;
+ goto error;
+ }
+ }
+ /*
+ * LTTNG_UST_TRACEPOINT_FIELD_LIST_GET needs to send the field
+ * after the reply.
+ */
+ if (lur.ret_code == USTCOMM_OK) {
+ switch (lum->cmd) {
+ case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET:
+ len = ustcomm_send_unix_sock(sock,
+ &args.field_list.entry,
+ sizeof(args.field_list.entry));
+ if (len != sizeof(args.field_list.entry)) {
+ ret = -1;
+ goto error;
+ }
+ }
}
/*
* We still have the memory map reference, and the fds have been
int ret;
if (sock_info->socket != -1) {
- ret = close(sock_info->socket);
+ ret = ustcomm_close_unix_sock(sock_info->socket);
if (ret) {
ERR("Error closing apps socket");
}
}
if (sock_info->socket != -1) {
- ret = close(sock_info->socket);
+ ret = ustcomm_close_unix_sock(sock_info->socket);
if (ret) {
ERR("Error closing %s apps socket", sock_info->name);
}
void __attribute__((constructor)) lttng_ust_init(void)
{
struct timespec constructor_timeout;
+ sigset_t sig_all_blocked, orig_parent_mask;
int timeout_mode;
int ret;
*/
lttng_fixup_event_tls();
lttng_fixup_ringbuffer_tls();
+ lttng_fixup_vtid_tls();
/*
* We want precise control over the order in which we construct
if (ret) {
ERR("Error setting up to local apps");
}
- ret = pthread_create(&local_apps.ust_listener, NULL,
- ust_listener_thread, &local_apps);
+
+ /* A new thread created by pthread_create inherits the signal mask
+ * from the parent. To avoid any signal being received by the
+ * listener thread, we block all signals temporarily in the parent,
+ * while we create the listener thread.
+ */
+ sigfillset(&sig_all_blocked);
+ ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask);
+ if (ret) {
+ PERROR("pthread_sigmask: %s", strerror(ret));
+ }
+
+ ret = pthread_create(&global_apps.ust_listener, NULL,
+ ust_listener_thread, &global_apps);
if (local_apps.allowed) {
- ret = pthread_create(&global_apps.ust_listener, NULL,
- ust_listener_thread, &global_apps);
+ ret = pthread_create(&local_apps.ust_listener, NULL,
+ ust_listener_thread, &local_apps);
} else {
handle_register_done(&local_apps);
}
+ /* Restore original signal mask in parent */
+ ret = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
+ if (ret) {
+ PERROR("pthread_sigmask: %s", strerror(ret));
+ }
+
switch (timeout_mode) {
case 1: /* timeout wait */
do {