Anything like GDestroyNotify in the mm api?

Jessy Exum jessy.diamondman at gmail.com
Mon Oct 5 08:05:18 UTC 2020


Hello Aleksander,

Thanks for the reply. You probably just saw my email I sent right before I
got your email.

I had never actually seen a memory leak. I didn't understand that the
callback would be ALWAYS called, so I assumed that there would be a leak
(mistakes made when working past midnight). Comparing the libmm-glib API to
other GObject based APIs made me feel like MM was missing a feature instead
of me just misunderstanding the behavior.

I attempted the 'solution' I described in the first email (listening for a
cancellation event). When I triggered a cancel, I deleted my object in the
cancel signal, and then the callback I registered with the MM function call
was triggered (as you just described). That caused a core dump :).

So the only thing wrong was me not understanding the guarantees of the API.

Now I just need to understand why even when I call mm_modem_create_bearer
and immediately cancel the GCancellable, My callback is called with the
error "Operation was cancelled", but the bearer is still created. This is
an unrelated issue, so I can create a new email thread on this question if
I can't figure it out.

Thanks for the excellent support,
Jessy Diamond Exum.

On Mon, Oct 5, 2020 at 12:51 AM Aleksander Morgado <aleksander at aleksander.es>
wrote:

> Hey Jessy,
>
> >
> > I am using MM in a C++ project, but my question won't be related to C++
> besides a very high level description of what I did.
> >
> > To get MM functions to invoke bound C++ functions as callbacks, I had to
> generate a small structure for each MM function call that automatically
> destroys itself once the callback fires. This works perfectly (mostly)!
> >
> > Except! If the MM function is cancelled, my wrapping structure is never
> invoked, never freed, and I get a memory leak. My current solution is to
> use g_cancellable_connect to trigger the struct's destruction when I cancel
> the MM operation. That is when I saw that g_cancellable_connect accepts an
> optional GDestroyNotify* callback, and I started thinking about how much
> more flexible the libmm-glib API would be if functions that accepted a
> GCancellable, callback, and userdata ALSO supported a GDestroyNotify style
> callback for freeing userdata.
> >
> > I know I can't expect a massive API change to a mature project because
> it would be convenient to one guy who is working in a different language,
> but I wanted to bring the idea up in case anyone else likes the idea, or
> knows why it was not implemented.
> >
>
> From the point of view of the user of libmm-glib APIs, you MUST assume
> that if you provide a GCallback to *any* async method, the GCallback
> will *always* be called for you. And always means always, when the
> async operation finishes successfully, when it fails, or when it's
> cancelled. This is a guarantee that the library gives you, and
> therefore if it doesn't happen, it's a bug in the library. Therefore,
> if you pass a GCallback with a user_data that you have allocated in
> heap, you're responsible for calling whatever free method that
> user_data requires once the GCallback has been called. If you're
> getting a memory leak, it could mean you're not doing this. Also, if
> you pass a GCallback, you should call the corresponding _finish()
> method of the async operation. This is not strictly needed in all
> cases, but I'd suggest to always call finish() unconditionally.
>
> If you look at the above, you'll see why you don't really need a
> GDestroyNotify in the async methods. Actually, none of the usual GIO
> async methods will ask you to provide a GDestroyNotify, because the
> guarantee that the callback is called always lets you run whatever
> free() you need yourself in the callback itself.
>
> The GDestroyNotify in g_cancellable_connect() is required so that you
> can safely assume the user_data is freed whenever the handler is
> disconnected (because you're really adding a signal handler) or the
> cancellation has happened (as this is a single-time event). This logic
> doesn't really apply to normal async methods like the ones we have in
> libmm-glib.
>
> So now, you say the GCallback is not being called if the operation is
> cancelled. Could you send a short tester to show this issue? Does the
> issue happen always with the same async method or with all that you've
> tried?
>
> --
> Aleksander
> https://aleksander.es
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/modemmanager-devel/attachments/20201005/9f4675ca/attachment-0001.htm>


More information about the ModemManager-devel mailing list