From: Florian Forster Date: Fri, 3 Feb 2012 09:54:58 +0000 (+0100) Subject: write_graphite plugin: Fix locking. X-Git-Tag: collectd-5.1.0~33^2~15 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=f7f4cc14a2eb055b6097a2946fd15bd2b8ac39e4;hp=917f8784060b467e67b4b05429ddd120be4bb845;p=collectd.git 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 --- 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); }