[libsoup/wip/constructor] Use a constructor to init the library



commit c5891e156a0f8047490bfe71bcb44a53a2545fbe
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Thu Sep 24 15:13:56 2015 +0200

    Use a constructor to init the library

 libsoup/Makefile.am    |    2 +
 libsoup/gconstructor.h |   94 ++++++++++++++++++++++++++++++++++++++++++++++++
 libsoup/soup-init.c    |   78 +++++++++++++++++++++++++++++++++++++++
 libsoup/soup-session.c |   52 +--------------------------
 4 files changed, 175 insertions(+), 51 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index a7dd7b2..345bd3e 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -101,6 +101,7 @@ libsoup_2_4_la_LIBADD =                     \
        $(SQLITE_LIBS)
 
 libsoup_2_4_la_SOURCES =               \
+       gconstructor.h                  \
        soup-address.c                  \
        soup-auth.c                     \
        soup-auth-basic.h               \
@@ -150,6 +151,7 @@ libsoup_2_4_la_SOURCES =            \
        soup-filter-input-stream.h      \
        soup-form.c                     \
        soup-headers.c                  \
+       soup-init.c                     \
        soup-io-stream.h                \
        soup-io-stream.c                \
        soup-logger.c                   \
diff --git a/libsoup/gconstructor.h b/libsoup/gconstructor.h
new file mode 100644
index 0000000..df98f83
--- /dev/null
+++ b/libsoup/gconstructor.h
@@ -0,0 +1,94 @@
+/*
+  If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and
+  destructors, in a sane way, including e.g. on library unload. If not you're on
+  your own.
+
+  Some compilers need #pragma to handle this, which does not work with macros,
+  so the way you need to use this is (for constructors):
+
+  #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+  #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
+  #endif
+  G_DEFINE_CONSTRUCTOR(my_constructor)
+  static void my_constructor(void) {
+   ...
+  }
+
+*/
+
+#ifndef __GTK_DOC_IGNORE__
+
+#if  __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void);
+#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void);
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
+/* Visual studio 2008 and later has _Pragma */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined (_MSC_VER)
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* Pre Visual studio 2008 must use #pragma section */
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined(__SUNPRO_C)
+
+/* This is not tested, but i believe it should work, based on:
+ * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c
+ */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  init(_func)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void);
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  fini(_func)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void);
+
+#else
+
+/* constructors not supported for this compiler */
+
+#endif
+
+#endif /* __GTK_DOC_IGNORE__ */
diff --git a/libsoup/soup-init.c b/libsoup/soup-init.c
new file mode 100644
index 0000000..92eb837
--- /dev/null
+++ b/libsoup/soup-init.c
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-session.c
+ *
+ * Copyright (C) 2000-2003, Ximian, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include "gconstructor.h"
+
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+HMODULE soup_dll;
+#endif
+
+static void
+soup_init (void)
+{
+#ifdef G_OS_WIN32
+       char *basedir = g_win32_get_package_installation_directory_of_module (soup_dll);
+       char *localedir = g_build_filename (basedir, "share", "locale", NULL);
+       bindtextdomain (GETTEXT_PACKAGE, localedir);
+       g_free (localedir);
+       g_free (basedir);
+#else
+       bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+#endif
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+}
+
+#if defined (G_OS_WIN32)
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+         DWORD     fdwReason,
+         LPVOID    lpvReserved)
+{
+       switch (fdwReason) {
+       case DLL_PROCESS_ATTACH:
+               soup_dll = hinstDLL;
+
+               soup_init ();
+               break;
+
+       case DLL_THREAD_DETACH:
+
+       default:
+               /* do nothing */
+               ;
+       }
+
+       return TRUE;
+}
+
+#elif defined (G_HAS_CONSTRUCTORS)
+
+#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(soup_init_ctor)
+#endif
+G_DEFINE_CONSTRUCTOR(soup_init_ctor)
+
+static void
+soup_init_ctor (void)
+{
+       soup_init ();
+}
+
+#else
+# error Your platform/compiler is missing constructor support
+#endif
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index aee6f37..3f84c69 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -77,54 +77,6 @@
  * subtypes) have a #SoupContentDecoder by default.
  **/
 
-#if defined (G_OS_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-BOOL WINAPI DllMain (HINSTANCE hinstDLL,
-                     DWORD     fdwReason,
-                     LPVOID    lpvReserved);
-
-HMODULE soup_dll;
-
-BOOL WINAPI
-DllMain (HINSTANCE hinstDLL,
-         DWORD     fdwReason,
-         LPVOID    lpvReserved)
-{
-       switch (fdwReason) {
-       case DLL_PROCESS_ATTACH:
-               soup_dll = hinstDLL;
-               break;
-
-       case DLL_THREAD_DETACH:
-
-       default:
-               /* do nothing */
-               ;
-       }
-
-       return TRUE;
-}
-#endif
-
-static void
-soup_init (void)
-{
-#ifdef G_OS_WIN32
-       char *basedir = g_win32_get_package_installation_directory_of_module (soup_dll);
-       char *localedir = g_build_filename (basedir, "share", "locale", NULL);
-       bindtextdomain (GETTEXT_PACKAGE, localedir);
-       g_free (localedir);
-       g_free (basedir);
-#else
-       bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
-#endif
-#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif
-}
-
 typedef struct {
        SoupURI     *uri;
        SoupAddress *addr;
@@ -220,9 +172,7 @@ static void async_send_request_running (SoupSession *session, SoupMessageQueueIt
 
 #define SOUP_SESSION_USER_AGENT_BASE "libsoup/" PACKAGE_VERSION
 
-G_DEFINE_TYPE_WITH_CODE (SoupSession, soup_session, G_TYPE_OBJECT,
-                        soup_init ();
-                        )
+G_DEFINE_TYPE (SoupSession, soup_session, G_TYPE_OBJECT)
 
 enum {
        REQUEST_QUEUED,


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