From a63c691b2f1d1dd4d212b27fea0534f2481ebcc8 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 26 Jun 2013 10:47:16 +0200 Subject: Fix compilation with older glibs configure.ac requires glib 2.24, but librest is making use of glib functions that were added in later releases (g_clear_object, g_simple_async_report_take_gerror_in_idle, ...). This commit adds reimplementation of these functions which will be used when an older glib is present at build time. glib-compat.[ch] come from spice-gtk. https://bugzilla.gnome.org/show_bug.cgi?id=703103 --- rest/Makefile.am | 2 + rest/glib-compat.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ rest/glib-compat.h | 53 +++++++++++++++++++++++++ rest/rest-private.h | 1 + rest/rest-proxy-auth.c | 1 + 5 files changed, 162 insertions(+) create mode 100644 rest/glib-compat.c create mode 100644 rest/glib-compat.h diff --git a/rest/Makefile.am b/rest/Makefile.am index 69e7f5b..f33fcf7 100644 --- a/rest/Makefile.am +++ b/rest/Makefile.am @@ -3,6 +3,8 @@ CLEANFILES = # For some reason I can't use $(librest_@API_VERSION@_la_SOURCES) in # test_runner_SOURCES, so we have to do this lib_sources = \ + glib-compat.h \ + glib-compat.c \ rest-param.c \ rest-params.c \ rest-proxy.c \ diff --git a/rest/glib-compat.c b/rest/glib-compat.c new file mode 100644 index 0000000..01e2c9a --- /dev/null +++ b/rest/glib-compat.c @@ -0,0 +1,105 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "glib-compat.h" + +#if !GLIB_CHECK_VERSION(2,28,0) +/** + * g_simple_async_result_new_take_error: (skip) + * @source_object: (allow-none): a #GObject, or %NULL + * @callback: (scope async): a #GAsyncReadyCallback + * @user_data: (closure): user data passed to @callback + * @error: a #GError + * + * Creates a #GSimpleAsyncResult from an error condition, and takes over the + * caller's ownership of @error, so the caller does not need to free it anymore. + * + * Returns: a #GSimpleAsyncResult + * + * Since: 2.28 + **/ +G_GNUC_INTERNAL GSimpleAsyncResult * +g_simple_async_result_new_take_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); + + simple = g_simple_async_result_new (source_object, + callback, + user_data, NULL); + g_simple_async_result_take_error (simple, error); + + return simple; +} + +/** + * spice_simple_async_result_take_error: (skip) + * @simple: a #GSimpleAsyncResult + * @error: a #GError + * + * Sets the result from @error, and takes over the caller's ownership + * of @error, so the caller does not need to free it any more. + * + * Since: 2.28 + **/ +G_GNUC_INTERNAL void +g_simple_async_result_take_error (GSimpleAsyncResult *simple, + GError *error) +{ + /* this code is different from upstream */ + /* we can't avoid extra copy/free, since the simple struct is + opaque */ + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); +} + +/** + * g_simple_async_report_take_gerror_in_idle: (skip) + * @object: (allow-none): a #GObject, or %NULL + * @callback: a #GAsyncReadyCallback. + * @user_data: user data passed to @callback. + * @error: the #GError to report + * + * Reports an error in an idle function. Similar to + * g_simple_async_report_gerror_in_idle(), but takes over the caller's + * ownership of @error, so the caller does not have to free it any more. + * + * Since: 2.28 + **/ +G_GNUC_INTERNAL void +g_simple_async_report_take_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (!object || G_IS_OBJECT (object)); + g_return_if_fail (error != NULL); + + simple = g_simple_async_result_new_take_error (object, + callback, + user_data, + error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +#endif /* 2.28 */ diff --git a/rest/glib-compat.h b/rest/glib-compat.h new file mode 100644 index 0000000..9ce59e1 --- /dev/null +++ b/rest/glib-compat.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#ifndef GLIB_COMPAT_H +#define GLIB_COMPAT_H + +#include +#include + +#if !GLIB_CHECK_VERSION(2,28,0) +#define g_clear_object(object_ptr) \ + G_STMT_START { \ + /* Only one access, please */ \ + gpointer *_p = (gpointer) (object_ptr); \ + gpointer _o; \ + \ + do \ + _o = g_atomic_pointer_get (_p); \ + while G_UNLIKELY (!g_atomic_pointer_compare_and_exchange (_p, _o, NULL));\ + \ + if (_o) \ + g_object_unref (_o); \ + } G_STMT_END + +GSimpleAsyncResult * +g_simple_async_result_new_take_error (GObject *source_object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error); +void +g_simple_async_result_take_error(GSimpleAsyncResult *simple, + GError *error); +void +g_simple_async_report_take_gerror_in_idle (GObject *object, + GAsyncReadyCallback callback, + gpointer user_data, + GError *error); + +#endif /* glib 2.28 */ + +#endif /* GLIB_COMPAT_H */ diff --git a/rest/rest-private.h b/rest/rest-private.h index b0f1fe4..1a78f80 100644 --- a/rest/rest-private.h +++ b/rest/rest-private.h @@ -28,6 +28,7 @@ #include #include #include +#include "glib-compat.h" G_BEGIN_DECLS diff --git a/rest/rest-proxy-auth.c b/rest/rest-proxy-auth.c index 3d808d4..86cd197 100644 --- a/rest/rest-proxy-auth.c +++ b/rest/rest-proxy-auth.c @@ -22,6 +22,7 @@ #include #include +#include "rest-private.h" G_DEFINE_TYPE (RestProxyAuth, rest_proxy_auth, G_TYPE_OBJECT) -- cgit v1.2.1