Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
gobjectnotifyqueue.c
Go to the documentation of this file.
1#line 1 "glib-2.82.1/include/glib-2.0/gobject/gobjectnotifyqueue.c"
2/* GObject - GLib Type, Object, Parameter and Signal Library
3 * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21/* WARNING:
22 *
23 * This file is INSTALLED and other projects (outside of glib)
24 * #include its contents.
25 */
26
27#ifndef __G_OBJECT_NOTIFY_QUEUE_H__
28#define __G_OBJECT_NOTIFY_QUEUE_H__
29
30#include <string.h> /* memset */
31
32#include <glib-object.h>
33
35
36
37/* --- typedefs --- */
40typedef void (*GObjectNotifyQueueDispatcher) (GObject *object,
43
44
45/* --- structures --- */
59
61
62/* --- functions --- */
63static void
65{
66 GObjectNotifyQueue *nqueue = data;
67
68 g_slist_free (nqueue->pspecs);
70}
71
72static inline GObjectNotifyQueue*
74 GObjectNotifyContext *context)
75{
76 GObjectNotifyQueue *nqueue;
77
78 G_LOCK(notify_lock);
79 nqueue = g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
80 if (!nqueue)
81 {
83 nqueue->context = context;
84 g_datalist_id_set_data_full (&object->qdata, context->quark_notify_queue,
86 }
87
88 if (nqueue->freeze_count >= 65535)
89 g_critical("Free queue for %s (%p) is larger than 65535,"
90 " called g_object_freeze_notify() too often."
91 " Forgot to call g_object_thaw_notify() or infinite loop",
92 G_OBJECT_TYPE_NAME (object), object);
93 else
94 nqueue->freeze_count++;
95 G_UNLOCK(notify_lock);
96
97 return nqueue;
98}
99
100static inline void
102 GObjectNotifyQueue *nqueue)
103{
104 GObjectNotifyContext *context = nqueue->context;
105 GParamSpec *pspecs_mem[16], **pspecs, **free_me = NULL;
106 GSList *slist;
107 guint n_pspecs = 0;
108
109 g_return_if_fail (nqueue->freeze_count > 0);
111
112 G_LOCK(notify_lock);
113
114 /* Just make sure we never get into some nasty race condition */
115 if (G_UNLIKELY(nqueue->freeze_count == 0)) {
116 G_UNLOCK(notify_lock);
117 g_critical ("%s: property-changed notification for %s(%p) is not frozen",
118 G_STRFUNC, G_OBJECT_TYPE_NAME (object), object);
119 return;
120 }
121
122 nqueue->freeze_count--;
123 if (nqueue->freeze_count) {
124 G_UNLOCK(notify_lock);
125 return;
126 }
127
128 pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem;
129
130 for (slist = nqueue->pspecs; slist; slist = slist->next)
131 {
132 pspecs[n_pspecs++] = slist->data;
133 }
134 g_datalist_id_set_data (&object->qdata, context->quark_notify_queue, NULL);
135
136 G_UNLOCK(notify_lock);
137
138 if (n_pspecs)
139 context->dispatcher (object, n_pspecs, pspecs);
140 g_free (free_me);
141}
142
143static inline void
145 GObjectNotifyQueue *nqueue)
146{
147 g_return_if_fail (nqueue->freeze_count > 0);
148
149 G_LOCK(notify_lock);
150
151 g_slist_free (nqueue->pspecs);
152 nqueue->pspecs = NULL;
153 nqueue->n_pspecs = 0;
154
155 G_UNLOCK(notify_lock);
156}
157
158static inline void
160 GObjectNotifyQueue *nqueue,
161 GParamSpec *pspec)
162{
163 if (pspec->flags & G_PARAM_READABLE)
164 {
165 GParamSpec *redirect;
166
167 G_LOCK(notify_lock);
168
169 g_return_if_fail (nqueue->n_pspecs < 65535);
170
171 redirect = g_param_spec_get_redirect_target (pspec);
172 if (redirect)
173 pspec = redirect;
174
175 /* we do the deduping in _thaw */
176 if (g_slist_find (nqueue->pspecs, pspec) == NULL)
177 {
178 nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
179 nqueue->n_pspecs++;
180 }
181
182 G_UNLOCK(notify_lock);
183 }
184}
185
186/* NB: This function is not threadsafe, do not ever use it if
187 * you need a threadsafe notify queue.
188 * Use g_object_notify_queue_freeze() to acquire the queue and
189 * g_object_notify_queue_thaw() after you are done instead.
190 */
191static inline GObjectNotifyQueue*
193 GObjectNotifyContext *context)
194{
195 return g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
196}
197
199
200#endif /* __G_OBJECT_NOTIFY_QUEUE_H__ */
#define g_atomic_int_get(atomic)
Definition gatomic.h:529
GLIB_AVAILABLE_IN_ALL void g_datalist_id_set_data_full(GData **datalist, GQuark key_id, gpointer data, GDestroyNotify destroy_func)
#define g_datalist_id_set_data(dl, q, d)
Definition gdataset.h:104
GLIB_AVAILABLE_IN_ALL gpointer g_datalist_id_get_data(GData **datalist, GQuark key_id)
unsigned short guint16
Definition glibconfig.h:49
#define NULL
Definition gmacros.h:924
#define G_END_DECLS
Definition gmacros.h:910
#define G_STRFUNC
Definition gmacros.h:901
#define G_BEGIN_DECLS
Definition gmacros.h:909
#define G_UNLIKELY(expr)
Definition gmacros.h:1252
#define G_GNUC_UNUSED
Definition gmacros.h:644
GLIB_AVAILABLE_IN_ALL void g_free(gpointer mem)
#define g_new(struct_type, n_structs)
Definition gmem.h:315
#define g_return_if_fail(expr)
Definition gmessages.h:649
#define g_critical(...)
Definition gmessages.h:359
#define G_OBJECT_TYPE_NAME(object)
Definition gobject.h:108
void(* GObjectNotifyQueueDispatcher)(GObject *object, guint n_pspecs, GParamSpec **pspecs)
static void g_object_notify_queue_add(GObject *object G_GNUC_UNUSED, GObjectNotifyQueue *nqueue, GParamSpec *pspec)
typedefG_BEGIN_DECLS struct _GObjectNotifyContext GObjectNotifyContext
static void g_object_notify_queue_thaw(GObject *object, GObjectNotifyQueue *nqueue)
static void g_object_notify_queue_clear(GObject *object G_GNUC_UNUSED, GObjectNotifyQueue *nqueue)
static GObjectNotifyQueue * g_object_notify_queue_freeze(GObject *object, GObjectNotifyContext *context)
static void g_object_notify_queue_free(gpointer data)
static GObjectNotifyQueue * g_object_notify_queue_from_object(GObject *object, GObjectNotifyContext *context)
GOBJECT_AVAILABLE_IN_ALL GParamSpec * g_param_spec_get_redirect_target(GParamSpec *pspec)
@ G_PARAM_READABLE
Definition gparam.h:156
G_BEGIN_DECLS typedef guint32 GQuark
Definition gquark.h:38
#define g_slice_free(type, mem)
Definition gslice.h:81
#define g_slice_new0(type)
Definition gslice.h:62
GLIB_AVAILABLE_IN_ALL void g_slist_free(GSList *list)
GLIB_AVAILABLE_IN_ALL GSList * g_slist_prepend(GSList *list, gpointer data) G_GNUC_WARN_UNUSED_RESULT
GLIB_AVAILABLE_IN_ALL GSList * g_slist_find(GSList *list, gconstpointer data)
typedefG_BEGIN_DECLS struct _GSList GSList
Definition gslist.h:39
#define G_LOCK(name)
Definition gthread.h:137
#define G_LOCK_DEFINE_STATIC(name)
Definition gthread.h:112
#define G_UNLOCK(name)
Definition gthread.h:138
void * gpointer
Definition gtypes.h:109
unsigned int guint
Definition gtypes.h:61
GObjectNotifyQueueDispatcher dispatcher
GObjectNotifyContext * context
GData * qdata
Definition gobject.h:258
guint ref_count
Definition gobject.h:257
GParamFlags flags
Definition gparam.h:212