From: Mathieu Desnoyers Date: Sat, 9 Mar 2013 16:56:25 +0000 (-0500) Subject: Add mutex for channel wakeup fd update X-Git-Tag: v2.2.0-rc1~53 X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=commitdiff_plain;h=cb7378b3cf177d007917a82a5fe2514e2015bb26 Add mutex for channel wakeup fd update Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index e00caf15..18bf614b 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -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) diff --git a/libringbuffer/ring_buffer_frontend.c b/libringbuffer/ring_buffer_frontend.c index 5d1bc4ad..871d96d1 100644 --- a/libringbuffer/ring_buffer_frontend.c +++ b/libringbuffer/ring_buffer_frontend.c @@ -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,