summaryrefslogtreecommitdiff
path: root/packages/gtk2/src/glib/gthread.inc
blob: fa9d1b3fc6dd5faf03dc1c92680e2856f65fd7cf (plain)
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}