[libsoup] Fix the SOUP_METHOD_* and SOUP_URI_SCHEME_* defines to be threadsafe



commit aad40ac467d12a188aed01e543aef5016aa4d3cb
Author: Dan Winship <danw gnome org>
Date:   Thu Jul 2 21:28:53 2009 -0400

    Fix the SOUP_METHOD_* and SOUP_URI_SCHEME_* defines to be threadsafe
    
    Also fix/optimize a few other things in URI scheme canonicalization

 libsoup/soup-method.h |   33 ++++++++++++++++++---------------
 libsoup/soup-misc.h   |    2 ++
 libsoup/soup-uri.c    |    9 +++++----
 libsoup/soup-uri.h    |    5 +++--
 4 files changed, 28 insertions(+), 21 deletions(-)
---
diff --git a/libsoup/soup-method.h b/libsoup/soup-method.h
index f646fd2..e716b8e 100644
--- a/libsoup/soup-method.h
+++ b/libsoup/soup-method.h
@@ -7,6 +7,7 @@
 #define SOUP_METHOD_H 1
 
 #include <libsoup/soup-types.h>
+#include <libsoup/soup-misc.h>
 
 G_BEGIN_DECLS
 
@@ -33,24 +34,26 @@ G_BEGIN_DECLS
  * </programlisting></informalexample>
  **/
 
+#define _SOUP_INTERN_METHOD(method) (_SOUP_ATOMIC_INTERN_STRING (_SOUP_METHOD_##method, #method))
+
 /* HTTP/1.1 methods */
-#define SOUP_METHOD_OPTIONS   (_SOUP_METHOD_OPTIONS ? _SOUP_METHOD_OPTIONS : (_SOUP_METHOD_OPTIONS = g_intern_static_string ("OPTIONS")))
-#define SOUP_METHOD_GET       (_SOUP_METHOD_GET ? _SOUP_METHOD_GET : (_SOUP_METHOD_GET = g_intern_static_string ("GET")))
-#define SOUP_METHOD_HEAD      (_SOUP_METHOD_HEAD ? _SOUP_METHOD_HEAD : (_SOUP_METHOD_HEAD = g_intern_static_string ("HEAD")))
-#define SOUP_METHOD_POST      (_SOUP_METHOD_POST ? _SOUP_METHOD_POST : (_SOUP_METHOD_POST = g_intern_static_string ("POST")))
-#define SOUP_METHOD_PUT       (_SOUP_METHOD_PUT ? _SOUP_METHOD_PUT : (_SOUP_METHOD_PUT = g_intern_static_string ("PUT")))
-#define SOUP_METHOD_DELETE    (_SOUP_METHOD_DELETE ? _SOUP_METHOD_DELETE : (_SOUP_METHOD_DELETE = g_intern_static_string ("DELETE")))
-#define SOUP_METHOD_TRACE     (_SOUP_METHOD_TRACE ? _SOUP_METHOD_TRACE : (_SOUP_METHOD_TRACE = g_intern_static_string ("TRACE")))
-#define SOUP_METHOD_CONNECT   (_SOUP_METHOD_CONNECT ? _SOUP_METHOD_CONNECT : (_SOUP_METHOD_CONNECT = g_intern_static_string ("CONNECT")))
+#define SOUP_METHOD_OPTIONS   _SOUP_INTERN_METHOD (OPTIONS)
+#define SOUP_METHOD_GET       _SOUP_INTERN_METHOD (GET)
+#define SOUP_METHOD_HEAD      _SOUP_INTERN_METHOD (HEAD)
+#define SOUP_METHOD_POST      _SOUP_INTERN_METHOD (POST)
+#define SOUP_METHOD_PUT       _SOUP_INTERN_METHOD (PUT)
+#define SOUP_METHOD_DELETE    _SOUP_INTERN_METHOD (DELETE)
+#define SOUP_METHOD_TRACE     _SOUP_INTERN_METHOD (TRACE)
+#define SOUP_METHOD_CONNECT   _SOUP_INTERN_METHOD (CONNECT)
 
 /* WebDAV methods */
-#define SOUP_METHOD_PROPFIND  (_SOUP_METHOD_PROPFIND ? _SOUP_METHOD_PROPFIND : (_SOUP_METHOD_PROPFIND = g_intern_static_string ("PROPFIND")))
-#define SOUP_METHOD_PROPPATCH (_SOUP_METHOD_PROPPATCH ? _SOUP_METHOD_PROPPATCH : (_SOUP_METHOD_PROPPATCH = g_intern_static_string ("PROPPATCH")))
-#define SOUP_METHOD_MKCOL     (_SOUP_METHOD_MKCOL ? _SOUP_METHOD_MKCOL : (_SOUP_METHOD_MKCOL = g_intern_static_string ("MKCOL")))
-#define SOUP_METHOD_COPY      (_SOUP_METHOD_COPY ? _SOUP_METHOD_COPY : (_SOUP_METHOD_COPY = g_intern_static_string ("COPY")))
-#define SOUP_METHOD_MOVE      (_SOUP_METHOD_MOVE ? _SOUP_METHOD_MOVE : (_SOUP_METHOD_MOVE = g_intern_static_string ("MOVE")))
-#define SOUP_METHOD_LOCK      (_SOUP_METHOD_LOCK ? _SOUP_METHOD_LOCK : (_SOUP_METHOD_LOCK = g_intern_static_string ("LOCK")))
-#define SOUP_METHOD_UNLOCK    (_SOUP_METHOD_UNLOCK ? _SOUP_METHOD_UNLOCK : (_SOUP_METHOD_UNLOCK = g_intern_static_string ("UNLOCK")))
+#define SOUP_METHOD_PROPFIND  _SOUP_INTERN_METHOD (PROPFIND)
+#define SOUP_METHOD_PROPPATCH _SOUP_INTERN_METHOD (PROPPATCH)
+#define SOUP_METHOD_MKCOL     _SOUP_INTERN_METHOD (MKCOL)
+#define SOUP_METHOD_COPY      _SOUP_INTERN_METHOD (COPY)
+#define SOUP_METHOD_MOVE      _SOUP_INTERN_METHOD (MOVE)
+#define SOUP_METHOD_LOCK      _SOUP_INTERN_METHOD (LOCK)
+#define SOUP_METHOD_UNLOCK    _SOUP_INTERN_METHOD (UNLOCK)
 
 /* Do not use these variables directly; use the macros above, which
  * ensure that they get initialized properly.
diff --git a/libsoup/soup-misc.h b/libsoup/soup-misc.h
index 162ddac..f8dde10 100644
--- a/libsoup/soup-misc.h
+++ b/libsoup/soup-misc.h
@@ -33,6 +33,8 @@ guint              soup_str_case_hash        (gconstpointer key);
 gboolean           soup_str_case_equal       (gconstpointer v1,
 					      gconstpointer v2);
 
+#define _SOUP_ATOMIC_INTERN_STRING(variable, value) (g_once_init_enter ((gsize *)&variable) ? (g_once_init_leave ((gsize *)&variable, GPOINTER_TO_SIZE (g_intern_static_string (value))), variable) : variable)
+
 /* SSL stuff */
 
 extern const gboolean soup_ssl_supported;
diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c
index 819e5cc..72a900d 100644
--- a/libsoup/soup-uri.c
+++ b/libsoup/soup-uri.c
@@ -100,16 +100,17 @@ const char *_SOUP_URI_SCHEME_HTTP, *_SOUP_URI_SCHEME_HTTPS;
 static inline const char *
 soup_uri_get_scheme (const char *scheme, int len)
 {
-	if (len == 4 && !strncmp (scheme, "http", 4)) {
+	if (len == 4 && !g_ascii_strncasecmp (scheme, "http", len)) {
 		return SOUP_URI_SCHEME_HTTP;
-	} else if (len == 5 && !strncmp (scheme, "https", 5)) {
+	} else if (len == 5 && !g_ascii_strncasecmp (scheme, "https", len)) {
 		return SOUP_URI_SCHEME_HTTPS;
 	} else {
 		char *lower_scheme;
 
 		lower_scheme = g_ascii_strdown (scheme, len);
-		scheme = g_intern_string (lower_scheme);
-		g_free (lower_scheme);
+		scheme = g_intern_static_string (lower_scheme);
+		if (scheme != (const char *)lower_scheme)
+			g_free (lower_scheme);
 		return scheme;
 	}
 }
diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h
index 32de7a3..c05f3f2 100644
--- a/libsoup/soup-uri.h
+++ b/libsoup/soup-uri.h
@@ -9,6 +9,7 @@
 #define  SOUP_URI_H 1
 
 #include <libsoup/soup-types.h>
+#include <libsoup/soup-misc.h>
 
 G_BEGIN_DECLS
 
@@ -30,8 +31,8 @@ struct _SoupURI {
 GType     soup_uri_get_type          (void);
 #define SOUP_TYPE_URI (soup_uri_get_type ())
 
-#define SOUP_URI_SCHEME_HTTP  (_SOUP_URI_SCHEME_HTTP ? _SOUP_URI_SCHEME_HTTP : (_SOUP_URI_SCHEME_HTTP = g_intern_static_string ("http")))
-#define SOUP_URI_SCHEME_HTTPS (_SOUP_URI_SCHEME_HTTPS ? _SOUP_URI_SCHEME_HTTPS : (_SOUP_URI_SCHEME_HTTPS = g_intern_static_string ("https")))
+#define SOUP_URI_SCHEME_HTTP  _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTP, "http")
+#define SOUP_URI_SCHEME_HTTPS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTPS, "https")
 extern const char *_SOUP_URI_SCHEME_HTTP, *_SOUP_URI_SCHEME_HTTPS;
 
 SoupURI  *soup_uri_new_with_base         (SoupURI    *base,



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