Correct connection sequence to maximize chances of e.g.: getting connected :)

Aleksander Morgado aleksander at aleksander.es
Thu May 7 07:34:46 UTC 2020


Hey!

> Sorry for deleting the quoted text every time, but without doing so, answers may result complicated to read confortably for me.
>
> So, in the end I came to the conclusion that using GObjects is probably the best course of cation :)
>
> So I am studying the GLib GObjects page for details, and started writing some code to try to understand things better.
>
> Goal: implement a GObject who can act as a container for:
> - MMObjects, MMModem objects, MMModemVoice objects
> - (long) integers for GSignals handlers and other data.
> I managed to get my code to compile, but would like some hints / recommendations on how I may proceed.
>

Ok.

> My header:
> #ifndef __main_h__
> #define __main_h__
>
> #include <glib-object.h>
> #include <libmm-glib.h>
>
> G_BEGIN_DECLS
> #define AV_TYPE_MODEM av_modem_get_type()
> G_DECLARE_DERIVABLE_TYPE(AvModem, av_modem, AV, MODEM, GObject)
>

In your case, you're probably not going to create subclasses of the
AvModem object, so you can easier use G_DECLARE_FINAL_TYPE and
completely avoid the need of having a "private" struct. With final
types, you can have all your internal data in the AvModem struct
itself.


> struct _AvModemClass {
>         MMObjectClass parent_class;
>
>         /* functions ... */

The functions in the class are only needed if you're going to subclass
the class, which you're not going to.

>         /* padding with things like
>         gpointer padding[12];
>         */

And padding is only required if you're making this class "public", in
order to leave some safe space to grow the class in the future. You
can also ignore this.

> };
>
> AvModem *av_modem_new(void);
>
> G_END_DECLS
>
> #endif
>
>
> Source:
> #include <glib.h>
> #include <main.h>
> #include <libmm-glib.h>
>
> typedef struct {
>         gchar *filename;
> } AvModemPrivate;
>

As said, if you use a final type you could add the filename variable
in the AvModem struct itself in the header. The ModemManager sources
don't do this because these macros were introduced in newer GLib
versions; we could probably do some porting now that we require newer
releases as well.

> G_DEFINE_TYPE_WITH_PRIVATE (AvModem, av_modem, G_TYPE_OBJECT)
>
> static void av_modem_init(AvModem *self) {
>         g_print("__FUNCTION__ invoked\n");
>         AvModemPrivate *priv = av_modem_get_instance_private(self);
>
>         /* here we would g_object_new and things */
>         /* initialize all public and private members to reasonable default values.
>          * They are all automatically initialized to 0 to begin with. */
> }
>
> static void av_modem_dispose(GObject *gobject) {
>         g_print("__FUNCTION__ invoked\n");
>         AvModemPrivate *priv = av_modem_get_instance_private(AV_MODEM(gobject));
>
>         /* In dispose(), you are supposed to free all types referenced from this
>          * object which might themselves hold a reference to self. Generally,
>          * the most simple solution is to unref all members on which you own a
>          * reference.
>          */
>
>         /* time to g_object_clear things */

Yes. It's very important that pointers in dispose() are re-set to NULL
after freeing. E.g. use g_clear_object(), g_clear_pointer() and such.
This is because dispose may be called multiple times.

>         G_OBJECT_CLASS (av_modem_parent_class)->dispose (gobject);
> }
>
> static void av_modem_finalize(GObject *gobject) {
>         g_print("__FUNCTION__ invoked\n");
>         AvModemPrivate *priv = av_modem_get_instance_private(AV_MODEM(gobject));
>
>         /* e.g.: g_free for filename */

Finalize is only called once, so no need to re-set pointers to NULL
after freeing.

>         G_OBJECT_CLASS (av_modem_parent_class)->finalize (gobject);
> }
>
> static void av_modem_class_init(AvModemClass *klass) {
>         g_print("__FUNCTION__ invoked\n");
>         GObjectClass *object_class = G_OBJECT_CLASS (klass);
>         object_class->dispose = av_modem_dispose;
>         object_class->finalize = av_modem_finalize;
> }
>
>
>
> gint main(void) {
>         return 0;
> }
>
> I see you use various convenience macros in libmm-glib headers, but I am trying to do things step by step to understand them.

The convenience macros are probably older GLib macros. The new macros
require less amount of them.

> I may have used GBoxed to wrap my own structs instead, but I am trying to do what's better.

You only need GBoxed for your own structs if they're going to be set
as object properties.

> I absoulutely need refcounting in this scenario. :)
>

Yes! (which is good)

-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list