Anything like GDestroyNotify in the mm api?

Aleksander Morgado aleksander at aleksander.es
Mon Oct 5 09:36:59 UTC 2020


> The real issue that is leading me through all of these tests is improving my understanding of lifecycles when working with async MM functions. I want to make sure that there is no possible scenario where I destroy one of my C++ objects that tracks a MMModem, in the destructor I cancel and unref the cancellable, the object is deleted, and then a callback comes through with the user_data set to my freed object and I get a use after free. But it is likely that this will just require me doing some more reading and experimentation. If you know any good practices to prevent these kinds of use after free issues, I would greatly appreciate any links or suggestions. (And thanks for not minding me changing the topic).
>

You can "solve" all possible use after frees by making sure the
reference count based lifecycle of the objects is kept in order. E.g.
if you need to pass a object to different async methods as user_data,
just make sure each time you pass it you give a "full reference" of
the object (g_object_ref()) so that you can be sure that by the time
the GCallback is called you are safe to g_object_unref() it.

E.g. a very stupid example:

MyObject *obj;

// this creates the first reference
obj = my_object_new();
// call an async method and pass a new full reference of the object as user_data
now_call_something_async (..., callback1, g_object_ref (obj));
// call another async method and pass a new full reference of the
object as user_data
now_call_something_else_async (..., callback2, g_object_ref (obj));
// call yet another async method and pass a new full reference of the
object as user_data
now_call_something_else_again_async (..., callback3, g_object_ref (obj));

// at this point you've scheduled 3 async operations, each receiving a
full reference to the object as user_data.
// so, you may want to unref the original reference you created and
leave the lifetime of the object to the
// references passed to the async methods
g_object_unref (obj);
return;

------------
And in the callback1(), callback2() and callback3() methods, you
should make sure you g_object_unref(obj) in each. That way you
guarantee the object is definitely valid in each of the callbacks, and
you also guarantee that the object will end up freed. What you cannot
guarantee is in which of the callbacks the final reference will be
unref-ed.

In GLib-based applications we use this reference count based logic *a
lot* and as long as you track the reference count of each object
properly, there will not be memory leaks.
-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list