Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
/* GLIB - Library of useful routines for C programming
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
2017-01-05 12:47:07 +01:00
|
|
|
* 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.
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
*
|
2011-10-04 20:31:33 -04:00
|
|
|
* 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
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2014-01-23 12:58:29 +01:00
|
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
|
|
|
* file for a list of people on the GLib Team. See the ChangeLog
|
|
|
|
* files for a list of changes. These files are distributed with
|
2008-03-14 19:30:38 +00:00
|
|
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
*/
|
|
|
|
|
2012-12-27 23:43:14 -05:00
|
|
|
#ifndef __G_THREAD_H__
|
|
|
|
#define __G_THREAD_H__
|
|
|
|
|
2011-10-12 00:24:46 -04:00
|
|
|
#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
|
2008-03-14 19:30:38 +00:00
|
|
|
#error "Only <glib.h> can be included directly."
|
|
|
|
#endif
|
|
|
|
|
2011-10-04 20:31:33 -04:00
|
|
|
#include <glib/gatomic.h>
|
2001-06-26 16:01:21 +00:00
|
|
|
#include <glib/gerror.h>
|
2015-02-09 15:42:01 +08:00
|
|
|
#include <glib/gutils.h>
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
|
2001-02-13 15:57:44 +00:00
|
|
|
#define G_THREAD_ERROR g_thread_error_quark ()
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
GQuark g_thread_error_quark (void);
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
|
|
|
|
} GThreadError;
|
|
|
|
|
2001-05-09 12:51:21 +00:00
|
|
|
typedef gpointer (*GThreadFunc) (gpointer data);
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
|
|
|
|
typedef struct _GThread GThread;
|
|
|
|
|
2011-10-02 20:59:15 -04:00
|
|
|
typedef union _GMutex GMutex;
|
2011-09-21 14:36:53 -04:00
|
|
|
typedef struct _GRecMutex GRecMutex;
|
2011-09-21 10:19:36 -04:00
|
|
|
typedef struct _GRWLock GRWLock;
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
typedef struct _GCond GCond;
|
|
|
|
typedef struct _GPrivate GPrivate;
|
2011-10-04 20:31:33 -04:00
|
|
|
typedef struct _GOnce GOnce;
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
|
2011-10-02 20:59:15 -04:00
|
|
|
union _GMutex
|
2011-09-16 18:05:23 -04:00
|
|
|
{
|
2011-10-02 20:59:15 -04:00
|
|
|
/*< private >*/
|
|
|
|
gpointer p;
|
|
|
|
guint i[2];
|
2011-09-21 10:19:36 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _GRWLock
|
|
|
|
{
|
2011-10-02 20:59:15 -04:00
|
|
|
/*< private >*/
|
|
|
|
gpointer p;
|
|
|
|
guint i[2];
|
2011-09-16 18:05:23 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _GCond
|
|
|
|
{
|
2011-10-02 20:59:15 -04:00
|
|
|
/*< private >*/
|
|
|
|
gpointer p;
|
|
|
|
guint i[2];
|
2011-09-16 18:05:23 -04:00
|
|
|
};
|
|
|
|
|
2011-09-21 14:36:53 -04:00
|
|
|
struct _GRecMutex
|
|
|
|
{
|
2011-10-02 20:59:15 -04:00
|
|
|
/*< private >*/
|
|
|
|
gpointer p;
|
|
|
|
guint i[2];
|
2011-09-21 14:36:53 -04:00
|
|
|
};
|
|
|
|
|
2011-09-30 14:22:04 -04:00
|
|
|
#define G_PRIVATE_INIT(notify) { NULL, (notify), { NULL, NULL } }
|
|
|
|
struct _GPrivate
|
|
|
|
{
|
2011-10-06 12:19:58 -04:00
|
|
|
/*< private >*/
|
2011-09-30 14:22:04 -04:00
|
|
|
gpointer p;
|
|
|
|
GDestroyNotify notify;
|
|
|
|
gpointer future[2];
|
|
|
|
};
|
|
|
|
|
2003-07-08 23:43:48 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
G_ONCE_STATUS_NOTCALLED,
|
|
|
|
G_ONCE_STATUS_PROGRESS,
|
2011-09-25 01:32:41 -04:00
|
|
|
G_ONCE_STATUS_READY
|
2003-07-08 23:43:48 +00:00
|
|
|
} GOnceStatus;
|
|
|
|
|
2011-10-04 20:31:33 -04:00
|
|
|
#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
|
2003-07-08 23:43:48 +00:00
|
|
|
struct _GOnce
|
|
|
|
{
|
|
|
|
volatile GOnceStatus status;
|
|
|
|
volatile gpointer retval;
|
|
|
|
};
|
|
|
|
|
2011-10-04 20:31:33 -04:00
|
|
|
#define G_LOCK_NAME(name) g__ ## name ## _lock
|
2011-08-31 14:01:45 -04:00
|
|
|
#define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
|
2011-10-02 20:51:38 -04:00
|
|
|
#define G_LOCK_DEFINE(name) GMutex G_LOCK_NAME (name)
|
2011-09-17 18:33:25 -04:00
|
|
|
#define G_LOCK_EXTERN(name) extern GMutex G_LOCK_NAME (name)
|
2011-08-31 14:01:45 -04:00
|
|
|
|
|
|
|
#ifdef G_DEBUG_LOCKS
|
|
|
|
# define G_LOCK(name) G_STMT_START{ \
|
|
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
|
|
"file %s: line %d (%s): locking: %s ", \
|
|
|
|
__FILE__, __LINE__, G_STRFUNC, \
|
|
|
|
#name); \
|
2011-09-17 18:33:25 -04:00
|
|
|
g_mutex_lock (&G_LOCK_NAME (name)); \
|
2011-08-31 14:01:45 -04:00
|
|
|
}G_STMT_END
|
|
|
|
# define G_UNLOCK(name) G_STMT_START{ \
|
|
|
|
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
|
|
"file %s: line %d (%s): unlocking: %s ", \
|
|
|
|
__FILE__, __LINE__, G_STRFUNC, \
|
|
|
|
#name); \
|
2011-09-17 18:33:25 -04:00
|
|
|
g_mutex_unlock (&G_LOCK_NAME (name)); \
|
2011-08-31 14:01:45 -04:00
|
|
|
}G_STMT_END
|
|
|
|
# define G_TRYLOCK(name) \
|
|
|
|
(g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
|
|
|
|
"file %s: line %d (%s): try locking: %s ", \
|
|
|
|
__FILE__, __LINE__, G_STRFUNC, \
|
2011-09-17 18:33:25 -04:00
|
|
|
#name), g_mutex_trylock (&G_LOCK_NAME (name)))
|
2011-08-31 14:01:45 -04:00
|
|
|
#else /* !G_DEBUG_LOCKS */
|
2011-09-17 18:33:25 -04:00
|
|
|
# define G_LOCK(name) g_mutex_lock (&G_LOCK_NAME (name))
|
|
|
|
# define G_UNLOCK(name) g_mutex_unlock (&G_LOCK_NAME (name))
|
|
|
|
# define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name))
|
2011-08-31 14:01:45 -04:00
|
|
|
#endif /* !G_DEBUG_LOCKS */
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-13 00:29:04 -04:00
|
|
|
GThread * g_thread_ref (GThread *thread);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-13 00:29:04 -04:00
|
|
|
void g_thread_unref (GThread *thread);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
GThread * g_thread_new (const gchar *name,
|
|
|
|
GThreadFunc func,
|
2011-10-13 01:00:57 -04:00
|
|
|
gpointer data);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-15 09:48:10 -04:00
|
|
|
GThread * g_thread_try_new (const gchar *name,
|
2011-10-13 01:00:57 -04:00
|
|
|
GThreadFunc func,
|
2011-10-04 20:31:33 -04:00
|
|
|
gpointer data,
|
|
|
|
GError **error);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
GThread * g_thread_self (void);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_thread_exit (gpointer retval);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
gpointer g_thread_join (GThread *thread);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_thread_yield (void);
|
|
|
|
|
|
|
|
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_mutex_init (GMutex *mutex);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_mutex_clear (GMutex *mutex);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_mutex_lock (GMutex *mutex);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
gboolean g_mutex_trylock (GMutex *mutex);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_mutex_unlock (GMutex *mutex);
|
|
|
|
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_init (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_clear (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_writer_lock (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
gboolean g_rw_lock_writer_trylock (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_writer_unlock (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_reader_lock (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
gboolean g_rw_lock_reader_trylock (GRWLock *rw_lock);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rw_lock_reader_unlock (GRWLock *rw_lock);
|
|
|
|
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rec_mutex_init (GRecMutex *rec_mutex);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rec_mutex_clear (GRecMutex *rec_mutex);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rec_mutex_lock (GRecMutex *rec_mutex);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
gboolean g_rec_mutex_trylock (GRecMutex *rec_mutex);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_rec_mutex_unlock (GRecMutex *rec_mutex);
|
|
|
|
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_cond_init (GCond *cond);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_cond_clear (GCond *cond);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_cond_wait (GCond *cond,
|
|
|
|
GMutex *mutex);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_cond_signal (GCond *cond);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_cond_broadcast (GCond *cond);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-13 23:24:23 -04:00
|
|
|
gboolean g_cond_wait_until (GCond *cond,
|
2011-10-04 20:31:33 -04:00
|
|
|
GMutex *mutex,
|
2011-10-15 16:50:23 -04:00
|
|
|
gint64 end_time);
|
2011-10-04 20:31:33 -04:00
|
|
|
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
gpointer g_private_get (GPrivate *key);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_private_set (GPrivate *key,
|
|
|
|
gpointer value);
|
2012-11-14 14:59:42 +00:00
|
|
|
GLIB_AVAILABLE_IN_2_32
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_private_replace (GPrivate *key,
|
|
|
|
gpointer value);
|
|
|
|
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
gpointer g_once_impl (GOnce *once,
|
|
|
|
GThreadFunc func,
|
|
|
|
gpointer arg);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
gboolean g_once_init_enter (volatile void *location);
|
2012-12-06 14:04:59 -05:00
|
|
|
GLIB_AVAILABLE_IN_ALL
|
2011-10-04 20:31:33 -04:00
|
|
|
void g_once_init_leave (volatile void *location,
|
|
|
|
gsize result);
|
2011-09-16 18:05:23 -04:00
|
|
|
|
gthread: Use C11-style memory consistency to speed up g_once()
The g_once() function exists to call a callback function exactly once,
and to block multiple contending threads on its completion, then to
return its return value to all of them (so they all see the same value).
The full implementation of g_once() (in g_once_impl()) uses a mutex and
condition variable to achieve this, and is needed in the contended case,
where multiple threads need to be blocked on completion of the callback.
However, most of the times that g_once() is called, the callback will
already have been called, and it just needs to establish that it has
been called and to return the stored return value.
Previously, a fast path was used if we knew that memory barriers were
not needed on the current architecture to safely access two dependent
global variables in the presence of multi-threaded access. This is true
of all sequentially consistent architectures.
Checking whether we could use this fast path (if
`G_ATOMIC_OP_MEMORY_BARRIER_NEEDED` was *not* defined) was a bit of a
pain, though, as it required GLib to know the memory consistency model
of every architecture. This kind of knowledge is traditionally a
compiler’s domain.
So, simplify the fast path by using the compiler-provided atomic
intrinsics, and acquire-release memory consistency semantics, if they
are available. If they’re not available, fall back to always locking as
before.
We definitely need to use `__ATOMIC_ACQUIRE` in the macro implementation
of g_once(). We don’t actually need to make the `__ATOMIC_RELEASE`
changes in `gthread.c` though, since locking and unlocking a mutex
guarantees to insert a full compiler and hardware memory barrier
(enforcing sequential consistency). So the `__ATOMIC_RELEASE` changes
are only in there to make it obvious what stores are logically meant to
match up with the `__ATOMIC_ACQUIRE` loads in `gthread.h`.
Notably, only the second store (and the first load) has to be atomic.
i.e. When storing `once->retval` and `once->status`, the first store is
normal and the second is atomic. This is because the writes have a
happens-before relationship, and all (atomic or non-atomic) writes
which happen-before an atomic store/release are visible in the thread
doing an atomic load/acquire on the same atomic variable, once that load
is complete.
References:
* https://preshing.com/20120913/acquire-and-release-semantics/
* https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/_005f_005fatomic-Builtins.html
* https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
* https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1323
2020-02-13 16:31:24 +00:00
|
|
|
/* Use C11-style atomic extensions to check the fast path for status=ready. If
|
|
|
|
* they are not available, fall back to using a mutex and condition variable in
|
|
|
|
* g_once_impl().
|
|
|
|
*
|
|
|
|
* On the C11-style codepath, only the load of once->status needs to be atomic,
|
|
|
|
* as the writes to it and once->retval in g_once_impl() are related by a
|
|
|
|
* happens-before relation. Release-acquire semantics are defined such that any
|
|
|
|
* atomic/non-atomic write which happens-before a store/release is guaranteed to
|
|
|
|
* be seen by the load/acquire of the same atomic variable. */
|
|
|
|
#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && defined(__ATOMIC_SEQ_CST)
|
2011-10-04 20:31:33 -04:00
|
|
|
# define g_once(once, func, arg) \
|
gthread: Use C11-style memory consistency to speed up g_once()
The g_once() function exists to call a callback function exactly once,
and to block multiple contending threads on its completion, then to
return its return value to all of them (so they all see the same value).
The full implementation of g_once() (in g_once_impl()) uses a mutex and
condition variable to achieve this, and is needed in the contended case,
where multiple threads need to be blocked on completion of the callback.
However, most of the times that g_once() is called, the callback will
already have been called, and it just needs to establish that it has
been called and to return the stored return value.
Previously, a fast path was used if we knew that memory barriers were
not needed on the current architecture to safely access two dependent
global variables in the presence of multi-threaded access. This is true
of all sequentially consistent architectures.
Checking whether we could use this fast path (if
`G_ATOMIC_OP_MEMORY_BARRIER_NEEDED` was *not* defined) was a bit of a
pain, though, as it required GLib to know the memory consistency model
of every architecture. This kind of knowledge is traditionally a
compiler’s domain.
So, simplify the fast path by using the compiler-provided atomic
intrinsics, and acquire-release memory consistency semantics, if they
are available. If they’re not available, fall back to always locking as
before.
We definitely need to use `__ATOMIC_ACQUIRE` in the macro implementation
of g_once(). We don’t actually need to make the `__ATOMIC_RELEASE`
changes in `gthread.c` though, since locking and unlocking a mutex
guarantees to insert a full compiler and hardware memory barrier
(enforcing sequential consistency). So the `__ATOMIC_RELEASE` changes
are only in there to make it obvious what stores are logically meant to
match up with the `__ATOMIC_ACQUIRE` loads in `gthread.h`.
Notably, only the second store (and the first load) has to be atomic.
i.e. When storing `once->retval` and `once->status`, the first store is
normal and the second is atomic. This is because the writes have a
happens-before relationship, and all (atomic or non-atomic) writes
which happen-before an atomic store/release are visible in the thread
doing an atomic load/acquire on the same atomic variable, once that load
is complete.
References:
* https://preshing.com/20120913/acquire-and-release-semantics/
* https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/_005f_005fatomic-Builtins.html
* https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
* https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1323
2020-02-13 16:31:24 +00:00
|
|
|
((__atomic_load_n (&(once)->status, __ATOMIC_ACQUIRE) == G_ONCE_STATUS_READY) ? \
|
2011-10-04 20:31:33 -04:00
|
|
|
(once)->retval : \
|
|
|
|
g_once_impl ((once), (func), (arg)))
|
gthread: Use C11-style memory consistency to speed up g_once()
The g_once() function exists to call a callback function exactly once,
and to block multiple contending threads on its completion, then to
return its return value to all of them (so they all see the same value).
The full implementation of g_once() (in g_once_impl()) uses a mutex and
condition variable to achieve this, and is needed in the contended case,
where multiple threads need to be blocked on completion of the callback.
However, most of the times that g_once() is called, the callback will
already have been called, and it just needs to establish that it has
been called and to return the stored return value.
Previously, a fast path was used if we knew that memory barriers were
not needed on the current architecture to safely access two dependent
global variables in the presence of multi-threaded access. This is true
of all sequentially consistent architectures.
Checking whether we could use this fast path (if
`G_ATOMIC_OP_MEMORY_BARRIER_NEEDED` was *not* defined) was a bit of a
pain, though, as it required GLib to know the memory consistency model
of every architecture. This kind of knowledge is traditionally a
compiler’s domain.
So, simplify the fast path by using the compiler-provided atomic
intrinsics, and acquire-release memory consistency semantics, if they
are available. If they’re not available, fall back to always locking as
before.
We definitely need to use `__ATOMIC_ACQUIRE` in the macro implementation
of g_once(). We don’t actually need to make the `__ATOMIC_RELEASE`
changes in `gthread.c` though, since locking and unlocking a mutex
guarantees to insert a full compiler and hardware memory barrier
(enforcing sequential consistency). So the `__ATOMIC_RELEASE` changes
are only in there to make it obvious what stores are logically meant to
match up with the `__ATOMIC_ACQUIRE` loads in `gthread.h`.
Notably, only the second store (and the first load) has to be atomic.
i.e. When storing `once->retval` and `once->status`, the first store is
normal and the second is atomic. This is because the writes have a
happens-before relationship, and all (atomic or non-atomic) writes
which happen-before an atomic store/release are visible in the thread
doing an atomic load/acquire on the same atomic variable, once that load
is complete.
References:
* https://preshing.com/20120913/acquire-and-release-semantics/
* https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/_005f_005fatomic-Builtins.html
* https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
* https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1323
2020-02-13 16:31:24 +00:00
|
|
|
#else
|
|
|
|
# define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
|
|
|
|
#endif
|
2011-10-04 20:31:33 -04:00
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
# define g_once_init_enter(location) \
|
|
|
|
(G_GNUC_EXTENSION ({ \
|
|
|
|
G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
|
2019-11-26 22:33:03 -07:00
|
|
|
(void) (0 ? (gpointer) *(location) : NULL); \
|
2011-10-04 20:31:33 -04:00
|
|
|
(!g_atomic_pointer_get (location) && \
|
|
|
|
g_once_init_enter (location)); \
|
|
|
|
}))
|
|
|
|
# define g_once_init_leave(location, result) \
|
|
|
|
(G_GNUC_EXTENSION ({ \
|
|
|
|
G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \
|
2019-10-17 11:36:50 +02:00
|
|
|
0 ? (void) (*(location) = (result)) : (void) 0; \
|
2011-10-04 20:31:33 -04:00
|
|
|
g_once_init_leave ((location), (gsize) (result)); \
|
|
|
|
}))
|
|
|
|
#else
|
|
|
|
# define g_once_init_enter(location) \
|
|
|
|
(g_once_init_enter((location)))
|
|
|
|
# define g_once_init_leave(location, result) \
|
|
|
|
(g_once_init_leave((location), (gsize) (result)))
|
|
|
|
#endif
|
2011-09-17 22:00:27 -04:00
|
|
|
|
2012-12-17 10:47:53 -05:00
|
|
|
GLIB_AVAILABLE_IN_2_36
|
|
|
|
guint g_get_num_processors (void);
|
|
|
|
|
2015-02-05 10:35:42 -05:00
|
|
|
/**
|
|
|
|
* GMutexLocker:
|
|
|
|
*
|
|
|
|
* Opaque type. See g_mutex_locker_new() for details.
|
|
|
|
* Since: 2.44
|
|
|
|
*/
|
|
|
|
typedef void GMutexLocker;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_mutex_locker_new:
|
|
|
|
* @mutex: a mutex to lock
|
|
|
|
*
|
|
|
|
* Lock @mutex and return a new #GMutexLocker. Unlock with
|
|
|
|
* g_mutex_locker_free(). Using g_mutex_unlock() on @mutex
|
|
|
|
* while a #GMutexLocker exists can lead to undefined behaviour.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No allocation is performed, it is equivalent to a g_mutex_lock() call.
|
|
|
|
*
|
2015-02-05 10:35:42 -05:00
|
|
|
* This is intended to be used with g_autoptr(). Note that g_autoptr()
|
|
|
|
* is only available when using GCC or clang, so the following example
|
|
|
|
* will only work with those compilers:
|
|
|
|
* |[
|
|
|
|
* typedef struct
|
|
|
|
* {
|
|
|
|
* ...
|
|
|
|
* GMutex mutex;
|
|
|
|
* ...
|
|
|
|
* } MyObject;
|
|
|
|
*
|
|
|
|
* static void
|
|
|
|
* my_object_do_stuff (MyObject *self)
|
|
|
|
* {
|
|
|
|
* g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->mutex);
|
|
|
|
*
|
|
|
|
* // Code with mutex locked here
|
|
|
|
*
|
|
|
|
* if (cond)
|
|
|
|
* // No need to unlock
|
|
|
|
* return;
|
|
|
|
*
|
|
|
|
* // Optionally early unlock
|
|
|
|
* g_clear_pointer (&locker, g_mutex_locker_free);
|
|
|
|
*
|
|
|
|
* // Code with mutex unlocked here
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Returns: a #GMutexLocker
|
|
|
|
* Since: 2.44
|
|
|
|
*/
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
|
2015-02-05 10:35:42 -05:00
|
|
|
static inline GMutexLocker *
|
|
|
|
g_mutex_locker_new (GMutex *mutex)
|
|
|
|
{
|
|
|
|
g_mutex_lock (mutex);
|
|
|
|
return (GMutexLocker *) mutex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_mutex_locker_free:
|
|
|
|
* @locker: a GMutexLocker
|
|
|
|
*
|
|
|
|
* Unlock @locker's mutex. See g_mutex_locker_new() for details.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No memory is freed, it is equivalent to a g_mutex_unlock() call.
|
|
|
|
*
|
2015-02-05 10:35:42 -05:00
|
|
|
* Since: 2.44
|
|
|
|
*/
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_44
|
2015-02-05 10:35:42 -05:00
|
|
|
static inline void
|
|
|
|
g_mutex_locker_free (GMutexLocker *locker)
|
|
|
|
{
|
|
|
|
g_mutex_unlock ((GMutex *) locker);
|
|
|
|
}
|
|
|
|
|
2018-12-12 12:03:13 +01:00
|
|
|
/**
|
|
|
|
* GRecMutexLocker:
|
|
|
|
*
|
|
|
|
* Opaque type. See g_rec_mutex_locker_new() for details.
|
|
|
|
* Since: 2.60
|
|
|
|
*/
|
|
|
|
typedef void GRecMutexLocker;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rec_mutex_locker_new:
|
|
|
|
* @rec_mutex: a recursive mutex to lock
|
|
|
|
*
|
|
|
|
* Lock @rec_mutex and return a new #GRecMutexLocker. Unlock with
|
|
|
|
* g_rec_mutex_locker_free(). Using g_rec_mutex_unlock() on @rec_mutex
|
|
|
|
* while a #GRecMutexLocker exists can lead to undefined behaviour.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No allocation is performed, it is equivalent to a g_rec_mutex_lock() call.
|
|
|
|
*
|
2018-12-12 12:03:13 +01:00
|
|
|
* This is intended to be used with g_autoptr(). Note that g_autoptr()
|
|
|
|
* is only available when using GCC or clang, so the following example
|
|
|
|
* will only work with those compilers:
|
|
|
|
* |[
|
|
|
|
* typedef struct
|
|
|
|
* {
|
|
|
|
* ...
|
|
|
|
* GRecMutex rec_mutex;
|
|
|
|
* ...
|
|
|
|
* } MyObject;
|
|
|
|
*
|
|
|
|
* static void
|
|
|
|
* my_object_do_stuff (MyObject *self)
|
|
|
|
* {
|
|
|
|
* g_autoptr(GRecMutexLocker) locker = g_rec_mutex_locker_new (&self->rec_mutex);
|
|
|
|
*
|
|
|
|
* // Code with rec_mutex locked here
|
|
|
|
*
|
|
|
|
* if (cond)
|
|
|
|
* // No need to unlock
|
|
|
|
* return;
|
|
|
|
*
|
|
|
|
* // Optionally early unlock
|
|
|
|
* g_clear_pointer (&locker, g_rec_mutex_locker_free);
|
|
|
|
*
|
|
|
|
* // Code with rec_mutex unlocked here
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Returns: a #GRecMutexLocker
|
|
|
|
* Since: 2.60
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
|
2018-12-12 12:03:13 +01:00
|
|
|
static inline GRecMutexLocker *
|
|
|
|
g_rec_mutex_locker_new (GRecMutex *rec_mutex)
|
|
|
|
{
|
|
|
|
g_rec_mutex_lock (rec_mutex);
|
|
|
|
return (GRecMutexLocker *) rec_mutex;
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2018-12-12 12:03:13 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rec_mutex_locker_free:
|
|
|
|
* @locker: a GRecMutexLocker
|
|
|
|
*
|
|
|
|
* Unlock @locker's recursive mutex. See g_rec_mutex_locker_new() for details.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No memory is freed, it is equivalent to a g_rec_mutex_unlock() call.
|
|
|
|
*
|
2018-12-12 12:03:13 +01:00
|
|
|
* Since: 2.60
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_60
|
2018-12-12 12:03:13 +01:00
|
|
|
static inline void
|
|
|
|
g_rec_mutex_locker_free (GRecMutexLocker *locker)
|
|
|
|
{
|
|
|
|
g_rec_mutex_unlock ((GRecMutex *) locker);
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2018-12-12 12:03:13 +01:00
|
|
|
|
2019-05-09 16:27:47 +02:00
|
|
|
/**
|
|
|
|
* GRWLockWriterLocker:
|
|
|
|
*
|
|
|
|
* Opaque type. See g_rw_lock_writer_locker_new() for details.
|
|
|
|
* Since: 2.62
|
|
|
|
*/
|
|
|
|
typedef void GRWLockWriterLocker;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rw_lock_writer_locker_new:
|
|
|
|
* @rw_lock: a #GRWLock
|
|
|
|
*
|
|
|
|
* Obtain a write lock on @rw_lock and return a new #GRWLockWriterLocker.
|
|
|
|
* Unlock with g_rw_lock_writer_locker_free(). Using g_rw_lock_writer_unlock()
|
|
|
|
* on @rw_lock while a #GRWLockWriterLocker exists can lead to undefined
|
|
|
|
* behaviour.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No allocation is performed, it is equivalent to a g_rw_lock_writer_lock() call.
|
|
|
|
*
|
2019-05-09 16:27:47 +02:00
|
|
|
* This is intended to be used with g_autoptr(). Note that g_autoptr()
|
|
|
|
* is only available when using GCC or clang, so the following example
|
|
|
|
* will only work with those compilers:
|
|
|
|
* |[
|
|
|
|
* typedef struct
|
|
|
|
* {
|
|
|
|
* ...
|
|
|
|
* GRWLock rw_lock;
|
|
|
|
* GPtrArray *array;
|
|
|
|
* ...
|
|
|
|
* } MyObject;
|
|
|
|
*
|
|
|
|
* static gchar *
|
|
|
|
* my_object_get_data (MyObject *self, guint index)
|
|
|
|
* {
|
|
|
|
* g_autoptr(GRWLockReaderLocker) locker = g_rw_lock_reader_locker_new (&self->rw_lock);
|
|
|
|
*
|
|
|
|
* // Code with a read lock obtained on rw_lock here
|
|
|
|
*
|
|
|
|
* if (self->array == NULL)
|
|
|
|
* // No need to unlock
|
|
|
|
* return NULL;
|
|
|
|
*
|
|
|
|
* if (index < self->array->len)
|
|
|
|
* // No need to unlock
|
|
|
|
* return g_ptr_array_index (self->array, index);
|
|
|
|
*
|
|
|
|
* // Optionally early unlock
|
|
|
|
* g_clear_pointer (&locker, g_rw_lock_reader_locker_free);
|
|
|
|
*
|
|
|
|
* // Code with rw_lock unlocked here
|
|
|
|
* return NULL;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* static void
|
|
|
|
* my_object_set_data (MyObject *self, guint index, gpointer data)
|
|
|
|
* {
|
|
|
|
* g_autoptr(GRWLockWriterLocker) locker = g_rw_lock_writer_locker_new (&self->rw_lock);
|
|
|
|
*
|
|
|
|
* // Code with a write lock obtained on rw_lock here
|
|
|
|
*
|
|
|
|
* if (self->array == NULL)
|
|
|
|
* self->array = g_ptr_array_new ();
|
|
|
|
*
|
|
|
|
* if (cond)
|
|
|
|
* // No need to unlock
|
|
|
|
* return;
|
|
|
|
*
|
|
|
|
* if (index >= self->array->len)
|
|
|
|
* g_ptr_array_set_size (self->array, index+1);
|
|
|
|
* g_ptr_array_index (self->array, index) = data;
|
|
|
|
*
|
|
|
|
* // Optionally early unlock
|
|
|
|
* g_clear_pointer (&locker, g_rw_lock_writer_locker_free);
|
|
|
|
*
|
|
|
|
* // Code with rw_lock unlocked here
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Returns: a #GRWLockWriterLocker
|
|
|
|
* Since: 2.62
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
|
2019-05-09 16:27:47 +02:00
|
|
|
static inline GRWLockWriterLocker *
|
|
|
|
g_rw_lock_writer_locker_new (GRWLock *rw_lock)
|
|
|
|
{
|
|
|
|
g_rw_lock_writer_lock (rw_lock);
|
|
|
|
return (GRWLockWriterLocker *) rw_lock;
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2019-05-09 16:27:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rw_lock_writer_locker_free:
|
|
|
|
* @locker: a GRWLockWriterLocker
|
|
|
|
*
|
|
|
|
* Release a write lock on @locker's read-write lock. See
|
|
|
|
* g_rw_lock_writer_locker_new() for details.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No memory is freed, it is equivalent to a g_rw_lock_writer_unlock() call.
|
|
|
|
*
|
2019-05-09 16:27:47 +02:00
|
|
|
* Since: 2.62
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
|
2019-05-09 16:27:47 +02:00
|
|
|
static inline void
|
|
|
|
g_rw_lock_writer_locker_free (GRWLockWriterLocker *locker)
|
|
|
|
{
|
|
|
|
g_rw_lock_writer_unlock ((GRWLock *) locker);
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2019-05-09 16:27:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GRWLockReaderLocker:
|
|
|
|
*
|
|
|
|
* Opaque type. See g_rw_lock_reader_locker_new() for details.
|
|
|
|
* Since: 2.62
|
|
|
|
*/
|
|
|
|
typedef void GRWLockReaderLocker;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rw_lock_reader_locker_new:
|
|
|
|
* @rw_lock: a #GRWLock
|
|
|
|
*
|
|
|
|
* Obtain a read lock on @rw_lock and return a new #GRWLockReaderLocker.
|
|
|
|
* Unlock with g_rw_lock_reader_locker_free(). Using g_rw_lock_reader_unlock()
|
|
|
|
* on @rw_lock while a #GRWLockReaderLocker exists can lead to undefined
|
|
|
|
* behaviour.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No allocation is performed, it is equivalent to a g_rw_lock_reader_lock() call.
|
|
|
|
*
|
2019-05-09 16:27:47 +02:00
|
|
|
* This is intended to be used with g_autoptr(). For a code sample, see
|
|
|
|
* g_rw_lock_writer_locker_new().
|
|
|
|
*
|
|
|
|
* Returns: a #GRWLockReaderLocker
|
|
|
|
* Since: 2.62
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
|
2019-05-09 16:27:47 +02:00
|
|
|
static inline GRWLockReaderLocker *
|
|
|
|
g_rw_lock_reader_locker_new (GRWLock *rw_lock)
|
|
|
|
{
|
|
|
|
g_rw_lock_reader_lock (rw_lock);
|
|
|
|
return (GRWLockReaderLocker *) rw_lock;
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2019-05-09 16:27:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* g_rw_lock_reader_locker_free:
|
|
|
|
* @locker: a GRWLockReaderLocker
|
|
|
|
*
|
|
|
|
* Release a read lock on @locker's read-write lock. See
|
|
|
|
* g_rw_lock_reader_locker_new() for details.
|
|
|
|
*
|
2020-01-31 16:00:28 +01:00
|
|
|
* No memory is freed, it is equivalent to a g_rw_lock_reader_unlock() call.
|
|
|
|
*
|
2019-05-09 16:27:47 +02:00
|
|
|
* Since: 2.62
|
|
|
|
*/
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
2020-05-15 11:45:33 +01:00
|
|
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_62
|
2019-05-09 16:27:47 +02:00
|
|
|
static inline void
|
|
|
|
g_rw_lock_reader_locker_free (GRWLockReaderLocker *locker)
|
|
|
|
{
|
|
|
|
g_rw_lock_reader_unlock ((GRWLock *) locker);
|
|
|
|
}
|
2020-04-24 11:46:39 -04:00
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
2019-05-09 16:27:47 +02:00
|
|
|
|
Split glib.h into many header files mostly according to the resp.
2000-10-12 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* glib.h, galloca.h, garray.h, gasyncqueue.h, gbacktrace.h,
gcache.h, gcompletion.h, gconvert.h, gdataset.h, gdate.h, ghash.h,
ghook.h, giochannel.h, glist.h , gmacros.h, gmain.h, gmem.h,
gmessages.h, gnode.h, gprimes.h, gquark.h, gqueue.h, grand.h,
grel.h, gscanner.h, gslist.h, gstrfuncs.h, gstring.h, gthread.h,
gthreadpool.h, gtimer.h, gtree.h, gtypes.h, gutils.h: Split glib.h
into many header files mostly according to the resp. *.c-files.
* gmacros.h: Added G_BEGIN_DECLS and G_END_DECLS to mean: 'in case
of C++: extern "C" { ... }' analogous to glibc __BEGIN_DECLS and
__END_DECLS.
* configure.in, gerror.h, gfileutils.h, gshell.h, gspawn.h,
gunicode.h, : Changed guard-macro names to something more
consistent.
* configure.in, *.h: Use G_BEGIN_DECLS and G_END_DECLS.
2000-10-12 11:52:07 +00:00
|
|
|
G_END_DECLS
|
|
|
|
|
|
|
|
#endif /* __G_THREAD_H__ */
|