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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
//{$ifndef __G_THREAD_H__}
//{$define __G_THREAD_H__}
//{$include gerror.inc}
// {$include gtypes.inc}
{* GLib Thread support *}
function g_thread_error_quark : TGQuark; cdecl; external gthreadlib name 'g_thread_error_quark';
function G_THREAD_ERROR: TGQuark;
type
PGThreadError = ^TGThreadError;
TGThreadError = ( G_THREAD_ERROR_AGAIN { Resource temporarily unavailable });
TGThreadFunc = function (data:gpointer):gpointer;cdecl;
PGThreadPriority = ^TGThreadPriority;
TGThreadPriority = (G_THREAD_PRIORITY_LOW,
G_THREAD_PRIORITY_NORMAL,
G_THREAD_PRIORITY_HIGH,
G_THREAD_PRIORITY_URGENT);
PGThread = ^TGThread;
TGThread = record
func : TGThreadFunc;
data : gpointer;
joinable : gboolean;
priority : TGThreadPriority;
end;
PPGMutex = ^PGMutex;
PGMutex = pointer; // GMutex;
PGCond = pointer; // GCond;
PGPrivate = pointer; // GPrivate;
// typedef struct _GMutex* GStaticMutex;
PGStaticMutex = ^TGStaticMutex;
TGStaticMutex = PGMutex;
PGThreadFunctions = ^TGThreadFunctions;
TGThreadFunctions = record
mutex_new : function :PGMutex; cdecl;
mutex_lock : procedure (mutex:PGMutex); cdecl;
mutex_trylock : function (mutex:PGMutex):gboolean; cdecl;
mutex_unlock : procedure (mutex:PGMutex); cdecl;
mutex_free : procedure (mutex:PGMutex); cdecl;
cond_new : function :PGCond; cdecl;
cond_signal : procedure (cond:PGCond); cdecl;
cond_broadcast : procedure (cond:PGCond); cdecl;
cond_wait : procedure (cond:PGCond; mutex:PGMutex); cdecl;
cond_timed_wait : function (cond:PGCond; mutex:PGMutex; end_time:PGTimeVal):gboolean; cdecl;
cond_free : procedure (cond:PGCond); cdecl;
private_new : function (dest:TGDestroyNotify):PGPrivate; cdecl;
private_get : function (private_key:PGPrivate):gpointer; cdecl;
private_set : procedure (private_key:PGPrivate; data:gpointer); cdecl;
thread_create : procedure (func:TGThreadFunc; data:gpointer; stack_size:gulong; joinable:gboolean; bound:gboolean;
priority:TGThreadPriority; thread:gpointer; error:PPGError); cdecl;
thread_yield : procedure ; cdecl;
thread_join : procedure (thread:gpointer); cdecl;
thread_exit : procedure ; cdecl;
thread_set_priority : procedure (thread:gpointer; priority:TGThreadPriority); cdecl;
thread_self : procedure (thread:gpointer); cdecl;
thread_equal : function (thread1:gpointer; thread2:gpointer):gboolean; cdecl;
end;
{$IFNDEF KYLIX}
var
{$IFDEF WIN32}
g_thread_functions_for_glib_use : TGThreadFunctions; external gliblib name 'g_thread_functions_for_glib_use';
g_thread_use_default_impl : gboolean; external gliblib name 'g_thread_use_default_impl';
g_threads_got_initialized : gboolean; external gliblib name 'g_threads_got_initialized';
{$ELSE}
g_thread_functions_for_glib_use : TGThreadFunctions;cvar;external; // ?????
g_thread_use_default_impl : gboolean;cvar;external;
g_threads_got_initialized : gboolean;cvar;external;
{$ENDIF}
{$ENDIF}
{ initializes the mutex/cond/private implementation for glib, might
only be called once, and must not be called directly or indirectly
from another glib-function, e.g. as a callback.
}
procedure g_thread_init(vtable:PGThreadFunctions);cdecl;external gthreadlib name 'g_thread_init';
{ Errorcheck mutexes. If you define G_ERRORCHECK_MUTEXES, then all
mutexes will check for re-locking and re-unlocking }
{ Initialize thread system with errorcheck mutexes. vtable must be
NULL. Do not call directly. Use #define G_ERRORCHECK_MUTEXES
instead.
}
procedure g_thread_init_with_errorcheck_mutexes(vtable:PGThreadFunctions);cdecl;external gthreadlib name 'g_thread_init_with_errorcheck_mutexes';
{ A random number to recognize debug calls to g_mutex_... }
const
G_MUTEX_DEBUG_MAGIC = $f8e18ad7;
{ internal function for fallback static mutex implementation }
function g_static_mutex_get_mutex_impl(mutex:PPGMutex):PGMutex;cdecl;external gthreadlib name 'g_static_mutex_get_mutex_impl';
{ shorthands for conditional and unconditional function calls }
function g_thread_supported: gboolean;
procedure g_mutex_lock (mutex: PGMutex);
function g_mutex_trylock (mutex: PGMutex):gboolean;
procedure g_mutex_unlock (mutex: PGMutex);
procedure g_mutex_free (mutex: PGMutex);
procedure g_cond_wait (cond: PGCond; mutex: PGMutex);
function g_cond_timed_wait (cond: PGCond;
mutex: PGMutex;
end_time: PGTimeVal):gboolean;
function g_mutex_new : PGMutex;
function g_cond_new : PGCond;
procedure g_cond_signal (cond: PGCond);
procedure g_cond_broadcast (cond: PGCond);
procedure g_cond_free (cond: PGCond);
function g_private_new (dest: TGDestroyNotify): PGPrivate;
function g_private_get (private_key: PGPrivate): gpointer;
procedure g_private_set (var private_key: PGPrivate; data: gpointer);
procedure g_thread_yield;
function g_thread_create (func: TGThreadFunc;
data: gpointer;
joinable: gboolean;
error: PPGError): PGThread;
function g_thread_create_full (func : TGThreadFunc;
data : gpointer;
stack_size: gulong;
joinable, bound: gboolean;
priority : TGThreadPriority;
error : ppGError): PGThread; cdecl; external gthreadlib name 'g_thread_create_full';
function g_thread_self:PGThread;cdecl;external gthreadlib name 'g_thread_self';
procedure g_thread_exit(retval:gpointer);cdecl;external gthreadlib name 'g_thread_exit';
function g_thread_join(thread:PGThread):gpointer;cdecl;external gthreadlib name 'g_thread_join';
procedure g_thread_set_priority(thread:PGThread; priority:TGThreadPriority);cdecl;external gthreadlib name 'g_thread_set_priority';
{ GStaticMutexes can be statically initialized with the value
G_STATIC_MUTEX_INIT, and then they can directly be used, that is
much easier, than having to explicitly allocate the mutex before
use
}
procedure g_static_mutex_lock (mutex: PGStaticMutex);
function g_static_mutex_trylock (mutex: PGStaticMutex): gboolean;
procedure g_static_mutex_unlock (mutex: PGStaticMutex);
procedure g_static_mutex_free(mutex:PGStaticMutex);cdecl;external gthreadlib name 'g_static_mutex_free';
type
PGStaticPrivate = ^TGStaticPrivate;
TGStaticPrivate = record
index : guint;
end;
const
nG_STATIC_PRIVATE_INIT = 0; //renamed because of conflict with function_name
procedure g_static_private_init(private_key:PGStaticPrivate);cdecl;external gthreadlib name 'g_static_private_init';
function g_static_private_get(private_key:PGStaticPrivate):gpointer;cdecl;external gthreadlib name 'g_static_private_get';
procedure g_static_private_set(private_key:PGStaticPrivate; data:gpointer; notify:TGDestroyNotify);cdecl;external gthreadlib name 'g_static_private_set';
procedure g_static_private_free(private_key:PGStaticPrivate);cdecl;external gthreadlib name 'g_static_private_free';
type
PGStaticRecMutex = ^TGStaticRecMutex;
TGStaticRecMutex = record
mutex : TGStaticMutex;
depth : guint;
owner : TGSystemThread; // defined in glibconfig.inc
end;
const
nG_STATIC_MUTEX_INIT = nil; // from glibconfig.h
nG_STATIC_REC_MUTEX_INIT = nG_STATIC_MUTEX_INIT;
procedure g_static_rec_mutex_init(mutex:PGStaticRecMutex);cdecl;external gthreadlib name 'g_static_rec_mutex_init';
procedure g_static_rec_mutex_lock(mutex:PGStaticRecMutex);cdecl;external gthreadlib name 'g_static_rec_mutex_lock';
function g_static_rec_mutex_trylock(mutex:PGStaticRecMutex):gboolean;cdecl;external gthreadlib name 'g_static_rec_mutex_trylock';
procedure g_static_rec_mutex_unlock(mutex:PGStaticRecMutex);cdecl;external gthreadlib name 'g_static_rec_mutex_unlock';
procedure g_static_rec_mutex_lock_full(mutex:PGStaticRecMutex; depth:guint);cdecl;external gthreadlib name 'g_static_rec_mutex_lock_full';
function g_static_rec_mutex_unlock_full(mutex:PGStaticRecMutex):guint;cdecl;external gthreadlib name 'g_static_rec_mutex_unlock_full';
procedure g_static_rec_mutex_free(mutex:PGStaticRecMutex);cdecl;external gthreadlib name 'g_static_rec_mutex_free';
type
PGStaticRWLock = ^TGStaticRWLock;
TGStaticRWLock = record
mutex : TGStaticMutex;
read_cond : PGCond;
write_cond : PGCond;
read_counter : guint;
write : gboolean;
want_to_read : guint;
want_to_write : guint;
end;
{* i can't translate this macro. any ideas???
*
* #define G_STATIC_RW_LOCK_INIT G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0
*}
procedure g_static_rw_lock_init(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_init';
procedure g_static_rw_lock_reader_lock(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_reader_lock';
function g_static_rw_lock_reader_trylock(lock:PGStaticRWLock):gboolean;cdecl;external gthreadlib name 'g_static_rw_lock_reader_trylock';
procedure g_static_rw_lock_reader_unlock(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_reader_unlock';
procedure g_static_rw_lock_writer_lock(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_writer_lock';
function g_static_rw_lock_writer_trylock(lock:PGStaticRWLock):gboolean;cdecl;external gthreadlib name 'g_static_rw_lock_writer_trylock';
procedure g_static_rw_lock_writer_unlock(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_writer_unlock';
procedure g_static_rw_lock_free(lock:PGStaticRWLock);cdecl;external gthreadlib name 'g_static_rw_lock_free';
{ these are some convenience macros that expand to nothing if GLib
was configured with --disable-threads. for using StaticMutexes,
you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
if you need to export the mutex. With G_LOCK_EXTERN (name) you can
declare such an globally defined lock. name is a unique identifier
for the protected varibale or code portion. locking, testing and
unlocking of such mutexes can be done with G_LOCK(), G_UNLOCK() and
G_TRYLOCK() respectively.
}
procedure glib_dummy_decl;cdecl;external gthreadlib name 'glib_dummy_decl';
{ anyone an idea???
#define G_LOCK_NAME(name) g__ ## name ## _lock
#define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name))
#define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name))
#define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
}
//{$endif}
|