Fix: There is more tests than the plan
[lttng-tools.git] / src / common / consumer-metadata-cache.c
index 5967a8eb296a51041f754622f65bb0b706ffe393..cbd3ef3945a5065017dbe1dc46c354fa10446aa5 100644 (file)
@@ -16,7 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <assert.h>
 #include <pthread.h>
 #include <stdlib.h>
@@ -46,14 +46,13 @@ static int extend_metadata_cache(struct lttng_consumer_channel *channel,
 {
        int ret = 0;
        char *tmp_data_ptr;
-       unsigned int new_size;
+       unsigned int new_size, old_size;
 
        assert(channel);
        assert(channel->metadata_cache);
 
-       new_size = max_t(unsigned int,
-                       channel->metadata_cache->cache_alloc_size + size,
-                       channel->metadata_cache->cache_alloc_size << 1);
+       old_size = channel->metadata_cache->cache_alloc_size;
+       new_size = max_t(unsigned int, old_size + size, old_size << 1);
        DBG("Extending metadata cache to %u", new_size);
        tmp_data_ptr = realloc(channel->metadata_cache->data, new_size);
        if (!tmp_data_ptr) {
@@ -62,6 +61,8 @@ static int extend_metadata_cache(struct lttng_consumer_channel *channel,
                ret = -1;
                goto end;
        }
+       /* Zero newly allocated memory */
+       memset(tmp_data_ptr + old_size, 0, new_size - old_size);
        channel->metadata_cache->data = tmp_data_ptr;
        channel->metadata_cache->cache_alloc_size = new_size;
 
@@ -71,8 +72,8 @@ end:
 
 /*
  * Write metadata to the cache, extend the cache if necessary. We support
- * non-contiguous updates but not overlapping ones. If there is contiguous
- * metadata in the cache, we send it to the ring buffer. The metadata cache
+ * overlapping updates, but they need to be contiguous. Send the
+ * contiguous metadata in cache to the ring buffer. The metadata cache
  * lock MUST be acquired to write in the cache.
  *
  * Return 0 on success, a negative value on error.
@@ -81,6 +82,7 @@ int consumer_metadata_cache_write(struct lttng_consumer_channel *channel,
                unsigned int offset, unsigned int len, char *data)
 {
        int ret = 0;
+       int size_ret;
        struct consumer_metadata_cache *cache;
 
        assert(channel);
@@ -99,20 +101,16 @@ int consumer_metadata_cache_write(struct lttng_consumer_channel *channel,
        }
 
        memcpy(cache->data + offset, data, len);
-       cache->total_bytes_written += len;
        if (offset + len > cache->max_offset) {
-               cache->max_offset = offset + len;
-       }
-
-       if (cache->max_offset == cache->total_bytes_written) {
                char dummy = 'c';
 
-               cache->contiguous = cache->max_offset;
+               cache->max_offset = offset + len;
                if (channel->monitor) {
-                       ret = write(channel->metadata_stream->ust_metadata_poll_pipe[1],
+                       size_ret = lttng_write(channel->metadata_stream->ust_metadata_poll_pipe[1],
                                        &dummy, 1);
-                       if (ret < 1) {
+                       if (size_ret < 1) {
                                ERR("Wakeup UST metadata pipe");
+                               ret = -1;
                                goto end;
                        }
                }
@@ -190,7 +188,7 @@ void consumer_metadata_cache_destroy(struct lttng_consumer_channel *channel)
  * Return 0 if everything has been flushed, 1 if there is data not flushed.
  */
 int consumer_metadata_cache_flushed(struct lttng_consumer_channel *channel,
-               uint64_t offset)
+               uint64_t offset, int timer)
 {
        int ret = 0;
        struct lttng_consumer_stream *metadata_stream;
@@ -199,12 +197,15 @@ int consumer_metadata_cache_flushed(struct lttng_consumer_channel *channel,
        assert(channel->metadata_cache);
 
        /*
-        * XXX This consumer_data.lock should eventually be replaced by
-        * a channel lock. It protects metadata_stream read and endpoint
-        * status check.
+        * If not called from a timer handler, we have to take the
+        * channel lock to be mutually exclusive with channel teardown.
+        * Timer handler does not need to take this lock because it is
+        * already synchronized by timer stop (and, more importantly,
+        * taking this lock in a timer handler would cause a deadlock).
         */
-       pthread_mutex_lock(&consumer_data.lock);
-       pthread_mutex_lock(&channel->lock);
+       if (!timer) {
+               pthread_mutex_lock(&channel->lock);
+       }
        pthread_mutex_lock(&channel->timer_lock);
        pthread_mutex_lock(&channel->metadata_cache->lock);
 
@@ -229,8 +230,9 @@ int consumer_metadata_cache_flushed(struct lttng_consumer_channel *channel,
 
        pthread_mutex_unlock(&channel->metadata_cache->lock);
        pthread_mutex_unlock(&channel->timer_lock);
-       pthread_mutex_unlock(&channel->lock);
-       pthread_mutex_unlock(&consumer_data.lock);
+       if (!timer) {
+               pthread_mutex_unlock(&channel->lock);
+       }
 
        return ret;
 }
This page took 0.026444 seconds and 5 git commands to generate.