Re: GLib "next cycle" update



On Sun, 2011-09-18 at 13:11 -0400, Ryan Lortie wrote:
>  - use a __attribute__((constructor)) approach
> 
>    I have a patch here to introduce this concept as a quick hack:
> 
>      http://git.gnome.org/browse/glib/commit/?h=wip/mutexes&id=9f29daafeb8133611a4ea24f5013ebb8bb623d73
> 
>    and two uses of it:
> 
>      http://git.gnome.org/browse/glib/commit/?h=wip/mutexes&id=7dd937f96b19f41d4eda4890dbbb57c6451cf4b6
>      http://git.gnome.org/browse/glib/commit/?h=wip/mutexes&id=233e66c195ae828f75ecff3738124041d7b1e586
> 
>    For the record, I think that this is a somewhat inelegant solution.
>    Maybe it's our best choice, though, given the constraints.  I know
>    some others want to make use of this, and maybe we could even
>    consider making the API public (and cleaning it up).
> 
>    I have doubts that we can ever support this everywhere in a portable
>    way but we can probably get pretty reasonable coverage.  Matthias
>    also raised some concern about the undefined order in which the
>    constructors could be called (which means that we might have to
>    refrain from calling gslice from other constructors, for example,
>    since gslice may not have been initialised yet).

I want this anyway as a public API, as I want to add a resource
framework, and we need it to automatically add any resources in a
library to the global resource table when loaded. I have done some
research on how to do this on most reasonable architectures, and I think
it is reasonable to demand it for all glib targets.

Unfortunately the API for this is gonna be *horrible* due to the
different ways it is implemented. Lets look at them:

On GCC we can just use a __attribute__((constructor)) marker on a
function, so it can be a normal macro. This works on both linux and osx,
and all other elf-based unixes using gcc.

For non-gcc solaris (i.e. sun cc) we can use #pragma init:
http://download.oracle.com/docs/cd/E19205-01/819-5267/bkbki/index.html

Unfortunately this is a pragma, which doesn't expand macro arguments, or
is possible to put in a macro. The only way to do this as an API is with
#include, so you'd do

#include <glib/glib-constructor-pre.h>
G_DEFINE_CONSTRUCTOR (my_constructor);
#include <glib/glib-constructor-post.h>

Which does something like:
glib-constructor-pre.h:

#define G_DEFINE_CONSTRUCTOR(func) \
  static void _glib_constructor (void) { \
    (func) (); \
  }
glib-constructor-post.h:
#pragma init(_glib_constructor)

Which, apart from looking ass, only works with one constructor per file.

For non-GCC windows (i.e. visual c) we can use this:
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc

This also uses pragmas, but doesn't have a fixed name at least, so the
one constructor per file doesn't apply.

As a last resort it is also possible to use the c++ compiler and create
a separate object file we can link into the app/library. This is harder
to use though, as it involves makefile trickery, etc.

>    A couple of solutions to that:
> 
>      - use the (priority) field of GCC
> 
>      - use internal rigging to ensure dependent inits are called first
>        or just use one big initialisation function that does it in the
>        right order

I think this is the right approach, its just plain more reliable and
debuggable.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]