Fix: liblttng-ust-fork Makefile flags mismatch
[lttng-ust.git] / liblttng-ust / lttng-ust-abi.c
index 1985d01864282200fe2a42aadf69a8f0b7a71bbe..ddadfc1d7f33c9a4fb9310976af296f33bdd66db 100644 (file)
@@ -69,6 +69,7 @@ struct lttng_ust_obj {
                        void *private_data;
                        const struct lttng_ust_objd_ops *ops;
                        int f_count;
+                       int owner_ref;  /* has ref from owner */
                        void *owner;
                        char name[OBJ_NAME_LEN];
                } s;
@@ -124,6 +125,7 @@ end:
        obj->u.s.ops = ops;
        obj->u.s.f_count = 2;   /* count == 1 : object is allocated */
                                /* count == 2 : allocated + hold ref */
+       obj->u.s.owner_ref = 1; /* One owner reference */
        obj->u.s.owner = owner;
        strncpy(obj->u.s.name, name, OBJ_NAME_LEN);
        obj->u.s.name[OBJ_NAME_LEN - 1] = '\0';
@@ -184,7 +186,7 @@ void objd_ref(int id)
        obj->u.s.f_count++;
 }
 
-int lttng_ust_objd_unref(int id)
+int lttng_ust_objd_unref(int id, int is_owner)
 {
        struct lttng_ust_obj *obj = _objd_get(id);
 
@@ -194,6 +196,13 @@ int lttng_ust_objd_unref(int id)
                ERR("Reference counting error\n");
                return -EINVAL;
        }
+       if (is_owner) {
+               if (!obj->u.s.owner_ref) {
+                       ERR("Error decrementing owner reference");
+                       return -EINVAL;
+               }
+               obj->u.s.owner_ref--;
+       }
        if ((--obj->u.s.f_count) == 1) {
                const struct lttng_ust_objd_ops *ops = objd_ops(id);
                
@@ -209,8 +218,16 @@ void objd_table_destroy(void)
 {
        int i;
 
-       for (i = 0; i < objd_table.allocated_len; i++)
-               (void) lttng_ust_objd_unref(i);
+       for (i = 0; i < objd_table.allocated_len; i++) {
+               struct lttng_ust_obj *obj;
+
+               obj = _objd_get(i);
+               if (!obj)
+                       continue;
+               if (!obj->u.s.owner_ref)
+                       continue;       /* only unref owner ref. */
+               (void) lttng_ust_objd_unref(i, 1);
+       }
        free(objd_table.array);
        objd_table.array = NULL;
        objd_table.len = 0;
@@ -230,8 +247,10 @@ void lttng_ust_objd_table_owner_cleanup(void *owner)
                        continue;
                if (!obj->u.s.owner)
                        continue;       /* skip root handles */
+               if (!obj->u.s.owner_ref)
+                       continue;       /* only unref owner ref. */
                if (obj->u.s.owner == owner)
-                       (void) lttng_ust_objd_unref(i);
+                       (void) lttng_ust_objd_unref(i, 1);
        }
 }
 
@@ -461,7 +480,7 @@ chan_error:
        {
                int err;
 
-               err = lttng_ust_objd_unref(chan_objd);
+               err = lttng_ust_objd_unref(chan_objd, 1);
                assert(!err);
        }
 objd_error:
@@ -598,7 +617,7 @@ alloc_error:
        {
                int err;
 
-               err = lttng_ust_objd_unref(list_objd);
+               err = lttng_ust_objd_unref(list_objd, 1);
                assert(!err);
        }
 objd_error:
@@ -681,7 +700,7 @@ alloc_error:
        {
                int err;
 
-               err = lttng_ust_objd_unref(list_objd);
+               err = lttng_ust_objd_unref(list_objd, 1);
                assert(!err);
        }
 objd_error:
@@ -785,7 +804,7 @@ event_error:
        {
                int err;
 
-               err = lttng_ust_objd_unref(event_objd);
+               err = lttng_ust_objd_unref(event_objd, 1);
                assert(!err);
        }
 objd_error:
@@ -902,7 +921,7 @@ int lttng_channel_release(int objd)
        struct lttng_channel *channel = objd_private(objd);
 
        if (channel)
-               return lttng_ust_objd_unref(channel->session->objd);
+               return lttng_ust_objd_unref(channel->session->objd, 0);
        return 0;
 }
 
@@ -965,7 +984,7 @@ int lttng_rb_release(int objd)
                if (!lttng_ust_abi_close_in_progress)
                        channel->ops->buffer_read_close(buf, channel->handle);
 
-               return lttng_ust_objd_unref(channel->objd);
+               return lttng_ust_objd_unref(channel->objd, 0);
        }
        return 0;
 }
@@ -1030,7 +1049,7 @@ int lttng_enabler_release(int objd)
        struct lttng_enabler *enabler = objd_private(objd);
 
        if (enabler)
-               return lttng_ust_objd_unref(enabler->chan->objd);
+               return lttng_ust_objd_unref(enabler->chan->objd, 0);
        return 0;
 }
 
This page took 0.028294 seconds and 4 git commands to generate.