P-p-H-d / mlib

Library of generic and type safe containers in pure C language (C99 or C11) for a wide collection of container (comparable to the C++ STL).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Vague description for i-shared's init

vladipus opened this issue · comments

The following description is kinda vague and may not actually represent what the actual method does. Does the "self" part of the struct has to be initialized before calling this method or not? Is the only part initialized with this method is intrusive-one?

I thought intrusive shared pointers could be used to reference statically allocated entities, but it seems like the INIT method is only called with init_new, which actually allocates data dynamically by default.

name_t name_init(type *object)
Return a shared pointer to 'object' which owns 'object'. The shared pointer part of 'object' shall not have been initialized, whereas other part of the object shall be initialized.

commented
  1. The self part of the struct may or may not be initialized before calling this method. There is no constraint. What this service does is initialized the ref counter of the structure. That's all.

  2. They can be used for statically allocated entities. But you cannot use _init_new method (that allocate a new object on the heap), but _init (and do the initialization yourself). I didn't want to call the INIT operator in the _init object since the basic object handled by the container is a pointer to object, not the object itself (I am not sure if it is a good idea or not). There are also some constraints that are not properly explained in the documentation: for statically allocated entities, you need to disable the operator NEW & DEL when expanding the oplist like this: (NEW(0), DEL(0)), so that the CLEAR method doesn't try to free the objects.

I can understand now. Maybe you should state the requirements clearer in the docs.
I have made my own version which is name_init_set_auto that actually initalizaes on the first retain, which is actually quite useful for shared static objects. You may also consider adding something like that to your repo:
image

This uses my own macro naming scheme, actually, but I think you get the idea.

Update on my side. I have decided to refactor this piece into a NEW-dependent branch. I've also added testing for NULL as I've found it also useful. Prefixed both methods with static for now as they seem only to be applicable for static shareds.
image

commented

I have updated the documentation.

Your _init_set_auto is interesting. I would call it rather like _init_once. I think also there is an issue in the thread synchronization. If there are 2 threads trying to call this function on the same object, it is possible that one thread starts using the object whereas the other hasn't finished initializing it.

For your test_null function, I think the test should be (ptr == NULL) || (atomic_load(&...)== 0) ?

  1. I actually like the once suffix more. It's more coherent, indeed.
    Right-on with a possible threading problem, also. Seems like the only way of doing so would be to use a mutex locking, since the atomics have only predefined set of operations on them, but we need to sync the whole INIT method.
  2. You're absolutely right. I've messed up with my frontend's is_active method logic. My bad.

Perhaps something like that would do the trick:
image

Including a special static macro version for the interface:
image

There is no point in data economy anyway, since it's a static in the end.

I think a once paradigm should be used here. I'll investigate more, but you can take a look: https://linux.die.net/man/3/pthread_once

Wow. You already have m_oncei_call in the lib. I'll try to use it then. Why is it called m_oncei ? That i seems kinda confusing, to be honest.

I have decided to refactor the whole static shareds into a separate concept, I've called module as there was too much coupling yet differences with the standard shared pointers. I'll get back to you, when I implement it completely.

Check this one also: https://gitlab.inria.fr/gustedt/p99
An interesting project, also seems mature. Maybe get there some ideas.

commented

You already have m_oncei_call in the lib. I'll try to use it then. Why is it called m_oncei ?

It is because I wanted to keep it as internal function for the moment (and not export it to the user).

I have completed my implementation for a Module concept. Take a look: https://github.com/vladipus/mlib/blob/master/m-module.h

commented

I have implemented the _init_once concept with the intrusive shared pointer (without adding a mutex / once object and keeping only the atomic_int) for simplicity.

Now that is SMART. Very interesting solution. I'll keep my module functionality as a separate feature, as I think it is, but the issue is solved now. Great work indeed!