glibcompat.h 5.44 KB
Newer Older
1 2 3 4
/*
 *  glibcompat.h - System-dependent definitions
 *
 *  Copyright (C) 2012 Intel Corporation
5
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 *  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, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifndef GLIB_COMPAT_H
#define GLIB_COMPAT_H

#include <glib.h>
27
#include <glib-object.h>
28

29 30 31 32 33 34 35
#define G_COMPAT_DEFINE(new_api, new_args, old_api, old_args)   \
static inline void                                              \
new_api new_args                                                \
{                                                               \
    old_api old_args;                                           \
}

36
#if !GLIB_CHECK_VERSION(2,27,2)
37 38 39 40 41 42 43 44
static inline void
g_list_free_full(GList *list, GDestroyNotify free_func)
{
    g_list_foreach(list, (GFunc)free_func, NULL);
    g_list_free(list);
}
#endif

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#if !GLIB_CHECK_VERSION(2,28,0)
static inline void
g_clear_object_inline(volatile GObject **object_ptr)
{
    gpointer * const ptr = (gpointer)object_ptr;
    gpointer old;

    do {
        old = g_atomic_pointer_get(ptr);
    } while G_UNLIKELY(!g_atomic_pointer_compare_and_exchange(ptr, old, NULL));

    if (old)
        g_object_unref(old);
}
#undef  g_clear_object
#define g_clear_object(obj) g_clear_object_inline((volatile GObject **)(obj))
#endif

63
#if !GLIB_CHECK_VERSION(2,31,2)
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
typedef GStaticMutex GCompatMutex;
G_COMPAT_DEFINE(g_compat_mutex_init, (GCompatMutex *mutex),
                g_static_mutex_init, (mutex))
G_COMPAT_DEFINE(g_compat_mutex_clear, (GCompatMutex *mutex),
                g_static_mutex_free, (mutex))
G_COMPAT_DEFINE(g_compat_mutex_lock, (GCompatMutex *mutex),
                g_static_mutex_lock, (mutex))
G_COMPAT_DEFINE(g_compat_mutex_unlock, (GCompatMutex *mutex),
                g_static_mutex_unlock, (mutex))

typedef GStaticRecMutex GCompatRecMutex;
G_COMPAT_DEFINE(g_compat_rec_mutex_init, (GCompatRecMutex *mutex),
                g_static_rec_mutex_init, (mutex))
G_COMPAT_DEFINE(g_compat_rec_mutex_clear, (GCompatRecMutex *mutex),
                g_static_rec_mutex_free, (mutex))
G_COMPAT_DEFINE(g_compat_rec_mutex_lock, (GCompatRecMutex *mutex),
                g_static_rec_mutex_lock, (mutex))
G_COMPAT_DEFINE(g_compat_rec_mutex_unlock, (GCompatRecMutex *mutex),
                g_static_rec_mutex_unlock, (mutex))

typedef GCond *GCompatCond;
G_COMPAT_DEFINE(g_compat_cond_init, (GCompatCond *cond),
                *cond = g_cond_new, ())
G_COMPAT_DEFINE(g_compat_cond_clear, (GCompatCond *cond),
                if (*cond) g_cond_free, (*cond))
G_COMPAT_DEFINE(g_compat_cond_signal, (GCompatCond *cond),
                g_cond_signal, (*cond))
G_COMPAT_DEFINE(g_compat_cond_broadcast, (GCompatCond *cond),
                g_cond_broadcast, (*cond))
93 94
G_COMPAT_DEFINE(g_compat_cond_wait, (GCompatCond *cond, GCompatMutex *mutex),
                g_cond_wait, (*cond, g_static_mutex_get_mutex(mutex)))
95

96
static inline gboolean
97
g_cond_wait_until(GCompatCond *cond, GStaticMutex *mutex, gint64 end_time)
98 99 100 101 102 103 104
{
    gint64 diff_time;
    GTimeVal timeout;

    diff_time = end_time - g_get_monotonic_time();
    g_get_current_time(&timeout);
    g_time_val_add(&timeout, diff_time > 0 ? diff_time : 0);
105
    return g_cond_timed_wait(*cond, g_static_mutex_get_mutex(mutex), &timeout);
106
}
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134

#define GMutex                          GCompatMutex
#undef  g_mutex_init
#define g_mutex_init(mutex)             g_compat_mutex_init(mutex)
#undef  g_mutex_clear
#define g_mutex_clear(mutex)            g_compat_mutex_clear(mutex)
#undef  g_mutex_lock
#define g_mutex_lock(mutex)             g_compat_mutex_lock(mutex)
#undef  g_mutex_unlock
#define g_mutex_unlock(mutex)           g_compat_mutex_unlock(mutex)

#define GRecMutex                       GCompatRecMutex
#undef  g_rec_mutex_init
#define g_rec_mutex_init(mutex)         g_compat_rec_mutex_init(mutex)
#undef  g_rec_mutex_clear
#define g_rec_mutex_clear(mutex)        g_compat_rec_mutex_clear(mutex)
#undef  g_rec_mutex_lock
#define g_rec_mutex_lock(mutex)         g_compat_rec_mutex_lock(mutex)
#undef  g_rec_mutex_unlock
#define g_rec_mutex_unlock(mutex)       g_compat_rec_mutex_unlock(mutex)

#define GCond                           GCompatCond
#undef  g_cond_init
#define g_cond_init(cond)               g_compat_cond_init(cond)
#undef  g_cond_clear
#define g_cond_clear(cond)              g_compat_cond_clear(cond)
#undef  g_cond_signal
#define g_cond_signal(cond)             g_compat_cond_signal(cond)
135 136
#undef  g_cond_wait
#define g_cond_wait(cond, mutex)        g_compat_cond_wait(cond, mutex)
137 138
#endif

139 140 141 142 143 144 145 146 147 148 149 150
#if !GLIB_CHECK_VERSION(2,31,18)
static inline gpointer
g_async_queue_timeout_pop(GAsyncQueue *queue, guint64 timeout)
{
    GTimeVal end_time;

    g_get_current_time(&end_time);
    g_time_val_add(&end_time, timeout);
    return g_async_queue_timed_pop(queue, &end_time);
}
#endif

151 152
#undef G_COMPAT_DEFINE

153
#endif /* GLIB_COMPAT_H */