Win32 port

Havoc Pennington hp at redhat.com
Sun Jun 25 11:10:33 PDT 2006


Hi,

Cool. Where is the string coming from on Windows? (Am I just missing 
that part of the patch?) What I'm wondering is how does it get 
allocated/freed.

There's a pretty good test suite in dbus so don't be afraid to rip 'er 
up and refactor, in most cases breakage will be revealed by the suite.

There are maybe four kinds of opaque object in common use in 
dbus/glib/gtk style C programming...

  1. "allocated value objects"
     Can be identified by the presence of _new(), _free(), optional
     _copy() methods, passed around as a pointer (e.g. DBusMemPool,
     DBusMutex, GHashTable, GError, GMarkupParseContext)

  2. "true value objects"
     Can be copied with C assignment operator and allocated on stack;
     may have an _init() method but not _free() (e.g. DBusMessageIter,
     DBusSHAContext, GtkTextIter, GdkColor)

  3. "weird hybrid of 1 and 2"
     The usage is to allocate on stack, _init(), then later _free();
     using C assignment operator isn't allowed (e.g. DBusString,
     DBusError, DBusUserInfo). I use this a lot in dbus, but it's
     not used much in glib/gtk since #1 can always be used instead.
     The main value of the "weird hybrid" is that you avoid a memory
     allocation, which in most cases is silly overoptimization.

  4. "refcounted object"
     Similar to #1, but the object is reference counted rather than
     having a flat free() method.[1] (e.g. GObject, DBusConnection)

I'd rather DBusUID fit into one of these patterns. If there's no memory 
management on that windows UID, then you could use pattern #2, which 
would look something like:

.h:

/* it's OK to copy this by value; it will never have allocated fields */
typedef struct {
   void *dummy;
} DBusUID;

.c:

typedef struct {
   union {
     unsigned long unix;
     char *windows;
   } uid;
} DBusUIDReal;

void
_dbus_uid_init_unix(DBusUID *uid, unsigned long value)
{
   DBusUIDReal *real = (DBusUIDReal*) uid;
   _dbus_assert(sizeof(DBusUIDReal) <= sizeof(DBusUID));
   real->uid.unix = value;
}

That would involve relatively few changes to code, though I'd still 
rather pass it in to functions as "DBusUID *uid" and not "DBusUID uid" 
to match the usual pattern.

If the Windows UID needs memory management though, you need to use 
approach 1 or 3, approach 2 simply won't work. Either 1 or 3 is fine, 
they are more or less equivalent and should be the same amount of work.
With 1 and 3 passing by pointer and not value is of course required 
since C assignment isn't allowed.

btw, what about guid_t? What's up with that on Windows, should it get a 
parallel/identical treatment?

Havoc

[1] Sub-rule for refcounted objects if you're interested; for language 
binding reasons, public API objects have to be either immutable (so they 
can be treated as a by-value object despite the refcount) or they have 
to have "destroy notification" (so the language binding proxy can be 
deleted on finalization)


More information about the dbus mailing list