From f7f4cc14a2eb055b6097a2946fd15bd2b8ac39e4 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Fri, 3 Feb 2012 10:54:58 +0100 Subject: [PATCH 1/1] write_graphite plugin: Fix locking. wg_send_buffer() is called from wg_flush_nolock(). When calling wg_flush_nolock(), the thread has to hold cb->send_lock. Locking it again will fail, but this condition is not checked for. Then the lock is released twice which may result in concurrency issues. Change-Id: Ie3062d50e6545adeb95b3a1938837c1f26835a56 --- src/write_graphite.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/write_graphite.c b/src/write_graphite.c index de460d7c..6b16bec2 100644 --- a/src/write_graphite.c +++ b/src/write_graphite.c @@ -120,20 +120,15 @@ static int wg_send_buffer (struct wg_callback *cb) status, strerror (errno)); - pthread_mutex_trylock (&cb->send_lock); - - DEBUG ("write_graphite plugin: closing socket and restting fd " - "so reinit will occur"); close (cb->sock_fd); cb->sock_fd = -1; - pthread_mutex_unlock (&cb->send_lock); - return (-1); } return (0); } +/* NOTE: You must hold cb->send_lock when calling this function! */ static int wg_flush_nolock (cdtime_t timeout, struct wg_callback *cb) { int status; @@ -240,14 +235,20 @@ static void wg_callback_free (void *data) cb = data; + pthread_mutex_lock (&cb->send_lock); + wg_flush_nolock (/* timeout = */ 0, cb); close(cb->sock_fd); + cb->sock_fd = -1; + sfree(cb->node); sfree(cb->service); sfree(cb->prefix); sfree(cb->postfix); + pthread_mutex_destroy (&cb->send_lock); + sfree(cb); } -- 2.30.2