Add mutex for channel wakeup fd update
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 9 Mar 2013 16:56:25 +0000 (11:56 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 9 Mar 2013 16:56:25 +0000 (11:56 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust-ctl/ustctl.c
libringbuffer/ring_buffer_frontend.c

index e00caf15ec3ed57b187d56fd915a538daf720aca..18bf614babdd9db292243f4aee0d48761699b5f4 100644 (file)
@@ -953,6 +953,8 @@ struct ustctl_consumer_channel *
        }
        chan->chan->ops = &transport->ops;
        memcpy(&chan->attr, attr, sizeof(chan->attr));
+       chan->wait_fd = ustctl_channel_get_wait_fd(chan);
+       chan->wakeup_fd = ustctl_channel_get_wakeup_fd(chan);
        return chan;
 
 chan_error:
@@ -1042,19 +1044,27 @@ end:
 int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
 {
        struct channel *chan;
+       int ret;
 
        chan = consumer_chan->chan->chan;
-       return ring_buffer_channel_close_wait_fd(&chan->backend.config,
+       ret = ring_buffer_channel_close_wait_fd(&chan->backend.config,
                        chan, chan->handle);
+       if (!ret)
+               consumer_chan->wait_fd = -1;
+       return ret;
 }
 
 int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan)
 {
        struct channel *chan;
+       int ret;
 
        chan = consumer_chan->chan->chan;
-       return ring_buffer_channel_close_wakeup_fd(&chan->backend.config,
+       ret = ring_buffer_channel_close_wakeup_fd(&chan->backend.config,
                        chan, chan->handle);
+       if (!ret)
+               consumer_chan->wakeup_fd = -1;
+       return ret;
 }
 
 int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
index 5d1bc4adbcdf37007269b8b6e3f49db0b1c9688f..871d96d1c6e07848348cadbeb872d5a480214add 100644 (file)
@@ -112,6 +112,12 @@ struct switch_offsets {
 
 DEFINE_URCU_TLS(unsigned int, lib_ring_buffer_nesting);
 
+/*
+ * wakeup_fd_mutex protects wakeup fd use by timer from concurrent
+ * close.
+ */
+static pthread_mutex_t wakeup_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static
 void lib_ring_buffer_print_errors(struct channel *chan,
                                struct lttng_ust_lib_ring_buffer *buf, int cpu,
@@ -301,6 +307,7 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
 
        DBG("Timer for channel %p\n", chan);
 
+       pthread_mutex_lock(&wakeup_fd_mutex);
        if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
                for_each_possible_cpu(cpu) {
                        struct lttng_ust_lib_ring_buffer *buf =
@@ -316,6 +323,7 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
                        lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                                chan->handle);
        }
+       pthread_mutex_unlock(&wakeup_fd_mutex);
        return;
 }
 
@@ -912,6 +920,7 @@ int ring_buffer_stream_close_wakeup_fd(const struct lttng_ust_lib_ring_buffer_co
                        int cpu)
 {
        struct shm_ref *ref;
+       int ret;
 
        if (config->alloc == RING_BUFFER_ALLOC_GLOBAL) {
                cpu = 0;
@@ -920,7 +929,10 @@ int ring_buffer_stream_close_wakeup_fd(const struct lttng_ust_lib_ring_buffer_co
                        return -EINVAL;
        }
        ref = &chan->backend.buf[cpu].shmp._ref;
-       return shm_close_wakeup_fd(handle, ref);
+       pthread_mutex_lock(&wakeup_fd_mutex);
+       ret = shm_close_wakeup_fd(handle, ref);
+       pthread_mutex_unlock(&wakeup_fd_mutex);
+       return ret;
 }
 
 int lib_ring_buffer_open_read(struct lttng_ust_lib_ring_buffer *buf,
This page took 0.027263 seconds and 4 git commands to generate.