X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Flttng-ust-abi.c;h=5f4ba8916da496c0f0b0f5867a996e13fa9b39e1;hb=46050b1a32de8dd0a7b65347af630c4a77f433a1;hp=dca010c9f97353c68011eac4cab506f23d089804;hpb=1ea11eab9f65504b2d217ef16f53f52ff941c630;p=lttng-ust.git diff --git a/libust/lttng-ust-abi.c b/libust/lttng-ust-abi.c index dca010c9..5f4ba891 100644 --- a/libust/lttng-ust-abi.c +++ b/libust/lttng-ust-abi.c @@ -37,13 +37,6 @@ * by the caller. */ -struct obj; - -struct objd_ops { - long (*cmd)(int objd, unsigned int cmd, unsigned long arg); - int (*release)(int objd); -}; - struct obj { union { struct { @@ -100,7 +93,8 @@ int objd_alloc(void *private_data, const struct objd_ops *ops) end: obj->u.s.private_data = private_data; obj->u.s.ops = ops; - obj->u.s.f_count = 1; + obj->u.s.f_count = 2; /* count == 1 : object is allocated */ + /* count == 2 : allocated + hold ref */ return obj - objd_table.array; } @@ -109,6 +103,8 @@ struct obj *_objd_get(int id) { if (id >= objd_table.len) return NULL; + if (!objd_table.array[id].u.s.f_count) + return NULL; return &objd_table.array[id]; } @@ -128,11 +124,12 @@ void objd_set_private(int id, void *private_data) obj->u.s.private_data = private_data; } -static const struct objd_ops *objd_ops(int id) { struct obj *obj = _objd_get(id); - assert(obj); + + if (!obj) + return NULL; return obj->u.s.ops; } @@ -144,6 +141,8 @@ void objd_free(int id) assert(obj); obj->u.freelist_next = objd_table.freelist_head; objd_table.freelist_head = obj - objd_table.array; + assert(obj->u.s.f_count == 1); + obj->u.s.f_count = 0; /* deallocated */ } static @@ -159,9 +158,13 @@ int objd_unref(int id) if (!obj) return -EINVAL; - if (!(--obj->u.s.f_count)) { + if (obj->u.s.f_count == 1) { + ERR("Reference counting error\n"); + return -EINVAL; + } + if ((--obj->u.s.f_count) == 1) { const struct objd_ops *ops = objd_ops(id); - + if (ops->release) ops->release(id); objd_free(id); @@ -172,6 +175,18 @@ int objd_unref(int id) static void objd_table_destroy(void) { + int i; + + for (i = 0; i < objd_table.allocated_len; i++) { + struct obj *obj = _objd_get(i); + const struct objd_ops *ops; + + if (!obj) + continue; + ops = obj->u.s.ops; + if (ops->release) + ops->release(i); + } free(objd_table.array); } @@ -191,6 +206,15 @@ enum channel_type { METADATA_CHANNEL, }; +int lttng_abi_create_root_handle(void) +{ + int root_handle; + + root_handle = objd_alloc(NULL, <tng_ops); + assert(root_handle == 0); + return root_handle; +} + int lttng_abi_create_session(void) { struct ltt_session *session; @@ -333,7 +357,6 @@ create_error: return; /* not allowed to return error */ } -static int lttng_abi_create_channel(int session_objd, struct lttng_ust_channel *chan_param, enum channel_type channel_type)