> 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 _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel