File: gda-lockable.c

package info (click to toggle)
libgda5 5.2.4-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 75,256 kB
  • ctags: 49,218
  • sloc: ansic: 461,759; sh: 11,808; xml: 10,466; yacc: 5,160; makefile: 4,327; php: 1,416; java: 1,300; python: 896; sql: 879; perl: 116
file content (137 lines) | stat: -rw-r--r-- 4,242 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
93
94
95
96
97
98
99
100
101
102
103
104
105
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
135
136
137
/*
 * Copyright (C) 2008 - 2013 Vivien Malerba <malerba@gnome-db.org>
 * Copyright (C) 2010 David King <davidk@openismus.com>
 *
 * 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 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 St, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include <libgda/gda-lockable.h>

static GRecMutex init_rmutex;
#define MUTEX_LOCK() g_rec_mutex_lock(&init_rmutex)
#define MUTEX_UNLOCK() g_rec_mutex_unlock(&init_rmutex)
static void gda_lockable_class_init (gpointer g_class);

GType
gda_lockable_get_type (void)
{
	static GType type = 0;

	if (G_UNLIKELY (type == 0)) {
		static const GTypeInfo info = {
			sizeof (GdaLockableIface),
			(GBaseInitFunc) gda_lockable_class_init,
			(GBaseFinalizeFunc) NULL,
			(GClassInitFunc) NULL,
			NULL,
			NULL,
			0,
			0,
			(GInstanceInitFunc) NULL,
			0
		};
		
		MUTEX_LOCK();
		if (type == 0) {
			type = g_type_register_static (G_TYPE_INTERFACE, "GdaLockable", &info, 0);
			g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
		}
		MUTEX_UNLOCK();
	}
	return type;
}

static void
gda_lockable_class_init (G_GNUC_UNUSED gpointer g_class)
{
	static gboolean initialized = FALSE;

	MUTEX_LOCK();
	if (! initialized) {
		initialized = TRUE;
	}
	MUTEX_UNLOCK();
}

/**
 * gda_lockable_lock:
 * @lockable: a #GdaLockable object.
 *
 * Locks @lockable. If it is already locked by another thread, the current thread will block until it is unlocked 
 * by the other thread.
 *
 * This function can be used even if g_thread_init() has not yet been called, and, in that case, will do nothing.
 *
 * Note: unlike g_mutex_lock(), this method recursive, which means a thread can lock @lockable several times 
 * (and has to unlock it as many times to actually unlock it).
 */
void
gda_lockable_lock (GdaLockable *lockable)
{
	g_return_if_fail (GDA_IS_LOCKABLE (lockable));
	
	if (GDA_LOCKABLE_GET_CLASS (lockable)->i_lock)
		(GDA_LOCKABLE_GET_CLASS (lockable)->i_lock) (lockable);
	else
		g_warning ("Internal implementation error: %s() method not implemented\n", "i_lock");
}

/**
 * gda_lockable_trylock:
 * @lockable: a #GdaLockable object.
 *
 * Tries to lock @lockable. If it is already locked by another thread, then it immediately returns FALSE, otherwise
 * it locks @lockable.
 *
 * This function can be used even if g_thread_init() has not yet been called, and, in that case, will do nothing.
 *
 * Note: unlike g_mutex_lock(), this method recursive, which means a thread can lock @lockable several times 
 * (and has to unlock it as many times to actually unlock it).
 *
 * Returns: TRUE if the object has successfully been locked.
 */
gboolean
gda_lockable_trylock (GdaLockable *lockable)
{
	g_return_val_if_fail (GDA_IS_LOCKABLE (lockable), FALSE);
	
	if (GDA_LOCKABLE_GET_CLASS (lockable)->i_trylock)
		return (GDA_LOCKABLE_GET_CLASS (lockable)->i_trylock) (lockable);
	else {
		g_warning ("Internal implementation error: %s() method not implemented\n", "i_trylock");
		return FALSE;
	}
}

/**
 * gda_lockable_unlock:
 * @lockable: a #GdaLockable object.
 *
 * Unlocks @lockable. This method should not be called if the current does not already holds a lock on @lockable (having
 * used gda_lockable_lock() or gda_lockable_trylock()).
 *
 * This function can be used even if g_thread_init() has not yet been called, and, in that case, will do nothing.
 */
void
gda_lockable_unlock (GdaLockable *lockable)
{
	g_return_if_fail (GDA_IS_LOCKABLE (lockable));
	
	if (GDA_LOCKABLE_GET_CLASS (lockable)->i_unlock)
		(GDA_LOCKABLE_GET_CLASS (lockable)->i_unlock) (lockable);
	else
		g_warning ("Internal implementation error: %s() method not implemented\n", "i_unlock");
}