~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/pthread_xt.cc

  • Committer: Brian Aker
  • Date: 2009-10-15 00:22:33 UTC
  • mto: (1183.1.11 merge)
  • mto: This revision was merged to the branch mainline in revision 1198.
  • Revision ID: brian@gaz-20091015002233-fa4ao2mbc67wls91
First pass of information engine. OMG, ponies... is it so much easier to
deal with creating and engine.

The list table iterator though... its ass, needs to go. We should also
abstract out share. Very few engines need a custom one. Just say'in

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2005 PrimeBase Technologies GmbH
2
 
 *
3
 
 * PrimeBase XT
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * 2006-03-22   Paul McCullagh
20
 
 *
21
 
 * H&G2JCtL
22
 
 *
23
 
 * This file contains windows specific code
24
 
 */
25
 
 
26
 
#include "xt_config.h"
27
 
 
28
 
#ifdef XT_WIN
29
 
#include <my_pthread.h>
30
 
#else
31
 
#ifdef DRIZZLED
32
 
#include <unistd.h>
33
 
#endif
34
 
#include <sys/resource.h>
35
 
#endif
36
 
#include <errno.h>
37
 
#include <limits.h>
38
 
#include <string.h>
39
 
 
40
 
#include "pthread_xt.h"
41
 
#include "thread_xt.h"
42
 
 
43
 
#ifdef XT_WIN
44
 
 
45
 
xtPublic void xt_p_init_threading(void)
46
 
{
47
 
}
48
 
 
49
 
xtPublic int xt_p_set_normal_priority(pthread_t thr)
50
 
{
51
 
        if (!SetThreadPriority (thr, THREAD_PRIORITY_NORMAL))
52
 
                return GetLastError();
53
 
        return 0;
54
 
}
55
 
 
56
 
xtPublic int xt_p_set_low_priority(pthread_t thr)
57
 
{
58
 
        if (!SetThreadPriority (thr, THREAD_PRIORITY_LOWEST))
59
 
                return GetLastError();
60
 
        return 0;
61
 
}
62
 
 
63
 
xtPublic int xt_p_set_high_priority(pthread_t thr)
64
 
{
65
 
        if (!SetThreadPriority (thr, THREAD_PRIORITY_HIGHEST))
66
 
                return GetLastError();
67
 
        return 0;
68
 
}
69
 
 
70
 
#define XT_RWLOCK_MAGIC 0x78AC390E
71
 
 
72
 
#ifdef XT_THREAD_LOCK_INFO
73
 
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr, const char *n)
74
 
#else
75
 
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr)
76
 
#endif
77
 
{
78
 
        InitializeCriticalSection(&mutex->mt_cs);
79
 
#ifdef XT_THREAD_LOCK_INFO
80
 
        xt_thread_lock_info_init(&mutex->mt_lock_info, mutex);
81
 
        mutex->mt_name = n;
82
 
#endif
83
 
        return 0;
84
 
}
85
 
 
86
 
xtPublic int xt_p_mutex_destroy(xt_mutex_type *mutex)
87
 
{
88
 
        DeleteCriticalSection(&mutex->mt_cs);
89
 
#ifdef XT_THREAD_LOCK_INFO
90
 
        xt_thread_lock_info_free(&mutex->mt_lock_info);
91
 
#endif
92
 
        return 0;
93
 
}
94
 
 
95
 
xtPublic int xt_p_mutex_lock(xt_mutex_type *mx)
96
 
{
97
 
        EnterCriticalSection(&mx->mt_cs);
98
 
#ifdef XT_THREAD_LOCK_INFO
99
 
        xt_thread_lock_info_add_owner(&mx->mt_lock_info);
100
 
#endif
101
 
        return 0;
102
 
}
103
 
 
104
 
xtPublic int xt_p_mutex_unlock(xt_mutex_type *mx)
105
 
{
106
 
        LeaveCriticalSection(&mx->mt_cs);
107
 
#ifdef XT_THREAD_LOCK_INFO
108
 
        xt_thread_lock_info_release_owner(&mx->mt_lock_info);
109
 
#endif
110
 
        return 0;
111
 
}
112
 
 
113
 
xtPublic int xt_p_mutex_trylock(xt_mutex_type *mutex)
114
 
{
115
 
#if(_WIN32_WINNT >= 0x0400)
116
 
        /* NOTE: MySQL bug! was using?!
117
 
         * pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
118
 
         */
119
 
        if (TryEnterCriticalSection(&mutex->mt_cs)) {
120
 
#ifdef XT_THREAD_LOCK_INFO
121
 
                xt_thread_lock_info_add_owner(&mutex->mt_lock_info);
122
 
#endif
123
 
                return 0;
124
 
        }
125
 
        return WAIT_TIMEOUT;
126
 
#else
127
 
        EnterCriticalSection(&mutex->mt_cs);
128
 
#ifdef XT_THREAD_LOCK_INFO
129
 
        xt_thread_lock_info_add_owner(&mutex->mt_lock_info);
130
 
#endif
131
 
        return 0;
132
 
#endif
133
 
}
134
 
 
135
 
#ifdef XT_THREAD_LOCK_INFO
136
 
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwl, const pthread_condattr_t *attr, const char *n)
137
 
#else
138
 
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwl, const pthread_condattr_t *attr)
139
 
#endif
140
 
{
141
 
        int result;
142
 
 
143
 
        if (rwl == NULL)
144
 
                return ERROR_BAD_ARGUMENTS;
145
 
 
146
 
        rwl->rw_sh_count = 0;
147
 
        rwl->rw_ex_count = 0;
148
 
        rwl->rw_sh_complete_count = 0;
149
 
 
150
 
        result = xt_p_mutex_init_with_autoname(&rwl->rw_ex_lock, NULL);
151
 
        if (result != 0)
152
 
                goto failed;
153
 
 
154
 
        result = xt_p_mutex_init_with_autoname(&rwl->rw_sh_lock, NULL);
155
 
        if (result != 0)
156
 
                goto failed_2;
157
 
 
158
 
        result = pthread_cond_init(&rwl->rw_sh_cond, NULL);
159
 
        if (result != 0)
160
 
                goto failed_3;
161
 
 
162
 
        rwl->rw_magic = XT_RWLOCK_MAGIC;
163
 
#ifdef XT_THREAD_LOCK_INFO
164
 
        rwl->rw_name = n;
165
 
        xt_thread_lock_info_init(&rwl->rw_lock_info, rwl);
166
 
#endif
167
 
        return 0;
168
 
 
169
 
        failed_3:
170
 
        (void) xt_p_mutex_destroy(&rwl->rw_sh_lock);
171
 
 
172
 
        failed_2:
173
 
        (void) xt_p_mutex_destroy(&rwl->rw_ex_lock);
174
 
 
175
 
        failed:
176
 
        return result;
177
 
}
178
 
 
179
 
xtPublic int xt_p_rwlock_destroy(xt_rwlock_type *rwl)
180
 
{
181
 
        int result = 0, result1 = 0, result2 = 0;
182
 
 
183
 
        if (rwl == NULL)
184
 
                return ERROR_BAD_ARGUMENTS;
185
 
 
186
 
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
187
 
                return ERROR_BAD_ARGUMENTS;
188
 
 
189
 
        if ((result = xt_p_mutex_lock(&rwl->rw_ex_lock)) != 0)
190
 
                return result;
191
 
 
192
 
        if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0) {
193
 
                (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
194
 
                return result;
195
 
        }
196
 
 
197
 
        /*
198
 
         * Check whether any threads own/wait for the lock (wait for ex.access);
199
 
         * report "BUSY" if so.
200
 
         */
201
 
        if (rwl->rw_ex_count > 0 || rwl->rw_sh_count > rwl->rw_sh_complete_count) {
202
 
                result = xt_p_mutex_unlock(&rwl->rw_sh_lock);
203
 
                result1 = xt_p_mutex_unlock(&rwl->rw_ex_lock);
204
 
                result2 = ERROR_BUSY;
205
 
        }
206
 
        else {
207
 
                rwl->rw_magic = 0;
208
 
 
209
 
                if ((result = xt_p_mutex_unlock(&rwl->rw_sh_lock)) != 0)
210
 
                {
211
 
                        xt_p_mutex_unlock(&rwl->rw_ex_lock);
212
 
                        return result;
213
 
                }
214
 
 
215
 
                if ((result = xt_p_mutex_unlock(&rwl->rw_ex_lock)) != 0)
216
 
                        return result;
217
 
 
218
 
                result = pthread_cond_destroy(&rwl->rw_sh_cond);
219
 
                result1 = xt_p_mutex_destroy(&rwl->rw_sh_lock);
220
 
                result2 = xt_p_mutex_destroy(&rwl->rw_ex_lock);
221
 
        }
222
 
 
223
 
#ifdef XT_THREAD_LOCK_INFO
224
 
        xt_thread_lock_info_free(&rwl->rw_lock_info);
225
 
#endif
226
 
 
227
 
        return (result != 0) ? result : ((result1 != 0) ? result1 : result2);
228
 
}
229
 
 
230
 
 
231
 
xtPublic int xt_p_rwlock_rdlock(xt_rwlock_type *rwl)
232
 
{
233
 
        int result;
234
 
 
235
 
        if (rwl == NULL)
236
 
                return ERROR_BAD_ARGUMENTS;
237
 
 
238
 
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
239
 
                return ERROR_BAD_ARGUMENTS;
240
 
 
241
 
        if ((result = xt_p_mutex_lock(&rwl->rw_ex_lock)) != 0)
242
 
                return result;
243
 
 
244
 
        if (++rwl->rw_sh_count == INT_MAX) {
245
 
                if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0)
246
 
                {
247
 
                        (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
248
 
                        return result;
249
 
                }
250
 
 
251
 
                rwl->rw_sh_count -= rwl->rw_sh_complete_count;
252
 
                rwl->rw_sh_complete_count = 0;
253
 
 
254
 
                if ((result = xt_p_mutex_unlock(&rwl->rw_sh_lock)) != 0)
255
 
                {
256
 
                        (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
257
 
                        return result;
258
 
                }
259
 
        }
260
 
 
261
 
#ifdef XT_THREAD_LOCK_INFO
262
 
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
263
 
#endif
264
 
 
265
 
        return (xt_p_mutex_unlock (&(rwl->rw_ex_lock)));
266
 
}
267
 
 
268
 
xtPublic int xt_p_rwlock_wrlock(xt_rwlock_type *rwl)
269
 
{
270
 
        int result;
271
 
 
272
 
        if (rwl == NULL)
273
 
                return ERROR_BAD_ARGUMENTS;
274
 
 
275
 
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
276
 
                return ERROR_BAD_ARGUMENTS;
277
 
 
278
 
        if ((result = xt_p_mutex_lock (&rwl->rw_ex_lock)) != 0)
279
 
                return result;
280
 
 
281
 
        if ((result = xt_p_mutex_lock (&rwl->rw_sh_lock)) != 0) {
282
 
                (void) xt_p_mutex_unlock (&rwl->rw_ex_lock);
283
 
                return result;
284
 
        }
285
 
 
286
 
        if (rwl->rw_ex_count == 0) {
287
 
                if (rwl->rw_sh_complete_count > 0) {
288
 
                        rwl->rw_sh_count -= rwl->rw_sh_complete_count;
289
 
                        rwl->rw_sh_complete_count = 0;
290
 
                }
291
 
 
292
 
                if (rwl->rw_sh_count > 0) {
293
 
                        rwl->rw_sh_complete_count = -rwl->rw_sh_count;
294
 
 
295
 
                        do {
296
 
                                result = pthread_cond_wait (&rwl->rw_sh_cond, &rwl->rw_sh_lock.mt_cs);
297
 
                        }
298
 
                        while (result == 0 && rwl->rw_sh_complete_count < 0);
299
 
 
300
 
                        if (result == 0)
301
 
                                rwl->rw_sh_count = 0;
302
 
                }
303
 
        }
304
 
 
305
 
        if (result == 0)
306
 
                rwl->rw_ex_count++;
307
 
 
308
 
#ifdef XT_THREAD_LOCK_INFO
309
 
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
310
 
#endif
311
 
 
312
 
        return result;
313
 
}
314
 
 
315
 
xtPublic xtBool xt_p_rwlock_try_wrlock(xt_rwlock_type *rwl)
316
 
{
317
 
        int result;
318
 
 
319
 
        if (rwl == NULL)
320
 
                return FALSE;
321
 
 
322
 
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
323
 
                return FALSE;
324
 
 
325
 
        if ((result = xt_p_mutex_trylock(&rwl->rw_ex_lock)) != 0)
326
 
                return FALSE;
327
 
 
328
 
        if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0) {
329
 
                (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
330
 
                return FALSE;
331
 
        }
332
 
 
333
 
        if (rwl->rw_ex_count == 0) {
334
 
                if (rwl->rw_sh_complete_count > 0) {
335
 
                        rwl->rw_sh_count -= rwl->rw_sh_complete_count;
336
 
                        rwl->rw_sh_complete_count = 0;
337
 
                }
338
 
 
339
 
                if (rwl->rw_sh_count > 0) {
340
 
                        rwl->rw_sh_complete_count = -rwl->rw_sh_count;
341
 
 
342
 
                        do {
343
 
                                result = pthread_cond_wait (&rwl->rw_sh_cond, &rwl->rw_sh_lock.mt_cs);
344
 
                        }
345
 
                        while (result == 0 && rwl->rw_sh_complete_count < 0);
346
 
 
347
 
                        if (result == 0)
348
 
                                rwl->rw_sh_count = 0;
349
 
                }
350
 
        }
351
 
 
352
 
        if (result == 0)
353
 
                rwl->rw_ex_count++;
354
 
 
355
 
#ifdef XT_THREAD_LOCK_INFO
356
 
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
357
 
#endif
358
 
 
359
 
        return TRUE;
360
 
}
361
 
 
362
 
xtPublic int xt_p_rwlock_unlock(xt_rwlock_type *rwl)
363
 
{
364
 
        int result, result1;
365
 
 
366
 
        if (rwl == NULL)
367
 
                return (ERROR_BAD_ARGUMENTS);
368
 
 
369
 
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
370
 
                return ERROR_BAD_ARGUMENTS;
371
 
 
372
 
        if (rwl->rw_ex_count == 0) {
373
 
                if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0)
374
 
                        return result;
375
 
 
376
 
                if (++rwl->rw_sh_complete_count == 0)
377
 
                        result = pthread_cond_signal(&rwl->rw_sh_cond);
378
 
 
379
 
                result1 = xt_p_mutex_unlock(&rwl->rw_sh_lock);
380
 
        }
381
 
        else {
382
 
                rwl->rw_ex_count--;
383
 
 
384
 
                result = xt_p_mutex_unlock(&rwl->rw_sh_lock);
385
 
                result1 = xt_p_mutex_unlock(&rwl->rw_ex_lock);
386
 
        }
387
 
 
388
 
#ifdef XT_THREAD_LOCK_INFO
389
 
        xt_thread_lock_info_release_owner(&rwl->rw_lock_info);
390
 
#endif
391
 
 
392
 
        return ((result != 0) ? result : result1);
393
 
}
394
 
 
395
 
xtPublic int xt_p_cond_wait(xt_cond_type *cond, xt_mutex_type *mutex)
396
 
{
397
 
        return xt_p_cond_timedwait(cond, mutex, NULL);
398
 
}
399
 
 
400
 
xtPublic int xt_p_cond_timedwait(xt_cond_type *cond, xt_mutex_type *mt, struct timespec *abstime)
401
 
{
402
 
        pthread_mutex_t *mutex = &mt->mt_cs;
403
 
        int                             result;
404
 
        long                    timeout; 
405
 
        union ft64              now;
406
 
 
407
 
        if (abstime != NULL) {
408
 
                GetSystemTimeAsFileTime(&now.ft);
409
 
 
410
 
                timeout = (long)((abstime->tv.i64 - now.i64) / 10000);
411
 
                if (timeout < 0)
412
 
                        timeout = 0L;
413
 
                if (timeout > abstime->max_timeout_msec)
414
 
                        timeout = abstime->max_timeout_msec;
415
 
        }
416
 
        else
417
 
                timeout= INFINITE;
418
 
 
419
 
        WaitForSingleObject(cond->broadcast_block_event, INFINITE);
420
 
 
421
 
        EnterCriticalSection(&cond->lock_waiting);
422
 
        cond->waiting++;
423
 
        LeaveCriticalSection(&cond->lock_waiting);
424
 
 
425
 
        LeaveCriticalSection(mutex);
426
 
 
427
 
        result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
428
 
 
429
 
        EnterCriticalSection(&cond->lock_waiting);
430
 
        cond->waiting--;
431
 
        
432
 
        if (cond->waiting == 0) {
433
 
                /* The last waiter must reset the broadcast
434
 
                 * state (whther there was a broadcast or not)!
435
 
                 */
436
 
                ResetEvent(cond->events[xt_cond_type::BROADCAST]);
437
 
                SetEvent(cond->broadcast_block_event);
438
 
        }
439
 
        LeaveCriticalSection(&cond->lock_waiting);
440
 
        
441
 
        EnterCriticalSection(mutex);
442
 
 
443
 
        return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
444
 
}
445
 
 
446
 
xtPublic int xt_p_join(pthread_t thread, void **value)
447
 
{
448
 
        DWORD exitcode;
449
 
 
450
 
        while(1) {
451
 
                switch (WaitForSingleObject(thread, 10000)) {
452
 
                        case WAIT_OBJECT_0:
453
 
                                return 0;
454
 
                        case WAIT_TIMEOUT:
455
 
                                /* Don't do this! According to the Win docs:
456
 
                                 * _endthread automatically closes the thread handle
457
 
                                 * (whereas _endthreadex does not). Therefore, when using
458
 
                                 * _beginthread and _endthread, do not explicitly close the
459
 
                                 * thread handle by calling the Win32 CloseHandle API.
460
 
                                CloseHandle(thread);
461
 
                                 */
462
 
                                /* This is done so that if the thread was not [yet] in the running
463
 
                                 * state when this function was called we won't deadlock here.
464
 
                                 */
465
 
                                if (GetExitCodeThread(thread, &exitcode) && (exitcode == STILL_ACTIVE))
466
 
                                        break;
467
 
                                return 0;
468
 
                        case WAIT_FAILED:
469
 
                                return GetLastError();
470
 
                }
471
 
        }
472
 
 
473
 
        return 0;
474
 
}
475
 
 
476
 
#else // XT_WIN
477
 
 
478
 
#ifdef __darwin__
479
 
#define POLICY                  SCHED_RR
480
 
#else
481
 
#define POLICY                  pth_policy
482
 
#endif
483
 
 
484
 
static int pth_policy;
485
 
static int pth_normal_priority;
486
 
static int pth_min_priority;
487
 
static int pth_max_priority;
488
 
 
489
 
/* Return zero if the priority was set OK,
490
 
 * else errno.
491
 
 */
492
 
static int pth_set_priority(pthread_t thread, int priority)
493
 
{
494
 
        struct sched_param      sp;
495
 
 
496
 
        memset(&sp, 0, sizeof(struct sched_param));
497
 
        sp.sched_priority = priority;
498
 
        return pthread_setschedparam(thread, POLICY, &sp);
499
 
}
500
 
 
501
 
static void pth_get_priority_limits(void)
502
 
{
503
 
        XTThreadPtr                     self = NULL;
504
 
        struct sched_param      sp;
505
 
        int                                     err;
506
 
        int                                     start;
507
 
 
508
 
        /* Save original priority: */
509
 
        err = pthread_getschedparam(pthread_self(), &pth_policy, &sp);
510
 
        if (err) {
511
 
                xt_throw_errno(XT_CONTEXT, err);
512
 
                return;
513
 
        }
514
 
        pth_normal_priority = sp.sched_priority;
515
 
 
516
 
        start = sp.sched_priority;
517
 
 
518
 
#ifdef XT_FREEBSD 
519
 
        pth_min_priority = sched_get_priority_min(sched_getscheduler(0));
520
 
        pth_max_priority = sched_get_priority_max(sched_getscheduler(0));
521
 
#else
522
 
        /* Search for the minimum priority: */
523
 
        pth_min_priority = start;
524
 
        for (;;) {
525
 
                /* 2007-03-01: Corrected, pth_set_priority returns the error code
526
 
                 * (thanks to Hakan for pointing out this bug!)
527
 
                 */
528
 
                if (pth_set_priority(pthread_self(), pth_min_priority-1) != 0)
529
 
                        break;
530
 
                pth_min_priority--;
531
 
        }
532
 
 
533
 
        /* Search for the maximum priority: */
534
 
        pth_max_priority = start;
535
 
        for (;;) {
536
 
                if (pth_set_priority(pthread_self(), pth_max_priority+1) != 0)
537
 
                        break;
538
 
                pth_max_priority++;
539
 
        }
540
 
 
541
 
        /* Restore original priority: */
542
 
        pthread_setschedparam(pthread_self(), pth_policy, &sp);
543
 
#endif
544
 
}
545
 
 
546
 
xtPublic void xt_p_init_threading(void)
547
 
{
548
 
        pth_get_priority_limits();
549
 
}
550
 
 
551
 
xtPublic int xt_p_set_low_priority(pthread_t thr)
552
 
{
553
 
        if (pth_min_priority == pth_max_priority) {
554
 
                /* Under Linux the priority of normal (non-runtime)
555
 
                 * threads are set using the standard methods
556
 
                 * for setting process priority.
557
 
                 */
558
 
 
559
 
                /* We could set who == 0 because it should have the same affect
560
 
                 * as using the PID.
561
 
                 */
562
 
 
563
 
                /* -20 = highest, 20 = lowest */
564
 
                if (setpriority(PRIO_PROCESS, getpid(), 20) == -1)
565
 
                        return errno;
566
 
                return 0;
567
 
        }
568
 
        return pth_set_priority(thr, pth_min_priority);
569
 
}
570
 
 
571
 
xtPublic int xt_p_set_normal_priority(pthread_t thr)
572
 
{
573
 
        if (pth_min_priority == pth_max_priority) {
574
 
                if (setpriority(PRIO_PROCESS, getpid(), 0) == -1)
575
 
                        return errno;
576
 
                return 0;
577
 
        }
578
 
        return pth_set_priority(thr, pth_normal_priority);
579
 
}
580
 
 
581
 
xtPublic int xt_p_set_high_priority(pthread_t thr)
582
 
{
583
 
        if (pth_min_priority == pth_max_priority) {
584
 
                if (setpriority(PRIO_PROCESS, getpid(), -20) == -1) {
585
 
                        if (errno == EACCES) {
586
 
                               if (setpriority(PRIO_PROCESS, getpid(), 0) == -1) {
587
 
                                        if (errno != EACCES)
588
 
                                                return errno;
589
 
                                }
590
 
                        }
591
 
                }
592
 
                return 0;
593
 
        }
594
 
        return pth_set_priority(thr, pth_max_priority);
595
 
}
596
 
 
597
 
#ifdef DEBUG_LOCKING
598
 
 
599
 
xtPublic int xt_p_mutex_lock(xt_mutex_type *mutex, u_int line, const char *file)
600
 
{
601
 
        XTThreadPtr self = xt_get_self();
602
 
        int                     r;
603
 
 
604
 
        ASSERT_NS(mutex->mu_init == 12345);
605
 
        r = pthread_mutex_lock(&mutex->mu_plock);
606
 
        if (r == 0) {
607
 
                if (mutex->mu_trace)
608
 
                        printf("==LOCK mutex %d %s:%d\n", (int) mutex->mu_trace, file, (int) line);
609
 
                ASSERT_NS(!mutex->mu_locker);
610
 
                mutex->mu_locker = self;
611
 
                mutex->mu_line = line;
612
 
                mutex->mu_file = file;
613
 
        }
614
 
#ifdef XT_THREAD_LOCK_INFO
615
 
        xt_thread_lock_info_add_owner(&mutex->mu_lock_info);
616
 
#endif
617
 
        return r;
618
 
}
619
 
 
620
 
xtPublic int xt_p_mutex_unlock(xt_mutex_type *mutex)
621
 
{
622
 
        XTThreadPtr self = xt_get_self();
623
 
 
624
 
        ASSERT_NS(mutex->mu_init == 12345);
625
 
        ASSERT_NS(mutex->mu_locker == self);
626
 
        mutex->mu_locker = NULL;
627
 
        if (mutex->mu_trace)
628
 
                printf("UNLOCK mutex %d\n", (int) mutex->mu_trace);
629
 
#ifdef XT_THREAD_LOCK_INFO
630
 
        xt_thread_lock_info_release_owner(&mutex->mu_lock_info);
631
 
#endif
632
 
        return pthread_mutex_unlock(&mutex->mu_plock);
633
 
}
634
 
 
635
 
xtPublic int xt_p_mutex_destroy(xt_mutex_type *mutex)
636
 
{
637
 
        ASSERT_NS(mutex->mu_init == 12345 || !mutex->mu_init || mutex->mu_init == 11111);
638
 
        mutex->mu_init = 11111;
639
 
#ifdef XT_THREAD_LOCK_INFO
640
 
        xt_thread_lock_info_free(&mutex->mu_lock_info);
641
 
#endif
642
 
        return pthread_mutex_destroy(&mutex->mu_plock);
643
 
}
644
 
 
645
 
xtPublic int xt_p_mutex_trylock(xt_mutex_type *mutex)
646
 
{
647
 
        XTThreadPtr self = xt_get_self();
648
 
        int                     r;
649
 
 
650
 
        ASSERT_NS(mutex->mu_init == 12345);
651
 
        r = pthread_mutex_trylock(&mutex->mu_plock);
652
 
        if (r == 0) {
653
 
                ASSERT_NS(!mutex->mu_locker);
654
 
                mutex->mu_locker = self;
655
 
#ifdef XT_THREAD_LOCK_INFO
656
 
                xt_thread_lock_info_add_owner(&mutex->mu_lock_info);
657
 
#endif
658
 
        }
659
 
        return r;
660
 
}
661
 
 
662
 
#ifdef XT_THREAD_LOCK_INFO
663
 
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr, const char *n)
664
 
#else
665
 
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr)
666
 
#endif
667
 
{
668
 
        mutex->mu_init = 12345;
669
 
        mutex->mu_trace = FALSE;
670
 
        mutex->mu_locker = NULL;
671
 
#ifdef XT_THREAD_LOCK_INFO
672
 
        mutex->mu_name = n;
673
 
        xt_thread_lock_info_init(&mutex->mu_lock_info, mutex);
674
 
#endif
675
 
        return pthread_mutex_init(&mutex->mu_plock, attr);
676
 
}
677
 
 
678
 
xtPublic int xt_p_cond_wait(xt_cond_type *cond, xt_mutex_type *mutex)
679
 
{
680
 
        XTThreadPtr self = xt_get_self();
681
 
        int                     r;
682
 
 
683
 
        ASSERT_NS(mutex->mu_init == 12345);
684
 
        ASSERT_NS(mutex->mu_locker == self);
685
 
        mutex->mu_locker = NULL;
686
 
        r = pthread_cond_wait(cond, &mutex->mu_plock);
687
 
        ASSERT_NS(!mutex->mu_locker);
688
 
        mutex->mu_locker = self;
689
 
        return r;
690
 
}
691
 
 
692
 
xtPublic int xt_p_cond_timedwait(xt_cond_type *cond, xt_mutex_type *mutex, const struct timespec *abstime)
693
 
{
694
 
        XTThreadPtr self = xt_get_self();
695
 
        int                     r;
696
 
 
697
 
        ASSERT_NS(mutex->mu_init == 12345);
698
 
        ASSERT_NS(mutex->mu_locker == self);
699
 
        mutex->mu_locker = NULL;
700
 
        r = pthread_cond_timedwait(cond, &mutex->mu_plock, abstime);
701
 
        ASSERT_NS(!mutex->mu_locker);
702
 
        mutex->mu_locker = self;
703
 
        return r;
704
 
}
705
 
 
706
 
xtPublic int xt_p_rwlock_rdlock(xt_rwlock_type *rwlock)
707
 
{
708
 
        int r;
709
 
 
710
 
        ASSERT_NS(rwlock->rw_init == 67890);
711
 
        r = pthread_rwlock_rdlock(&rwlock->rw_plock);
712
 
#ifdef XT_THREAD_LOCK_INFO
713
 
        xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
714
 
#endif
715
 
        return r;
716
 
}
717
 
 
718
 
xtPublic int xt_p_rwlock_wrlock(xt_rwlock_type *rwlock)
719
 
{
720
 
        XTThreadPtr self = xt_get_self();
721
 
        int                     r;
722
 
 
723
 
        ASSERT_NS(rwlock->rw_init == 67890);
724
 
        r = pthread_rwlock_wrlock(&rwlock->rw_plock);
725
 
        if (r == 0) {
726
 
                ASSERT_NS(!rwlock->rw_locker);
727
 
                rwlock->rw_locker = self;
728
 
        }
729
 
#ifdef XT_THREAD_LOCK_INFO
730
 
        xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
731
 
#endif
732
 
        return r;
733
 
}
734
 
 
735
 
xtPublic xtBool xt_p_rwlock_try_wrlock(xt_rwlock_type *rwlock)
736
 
{
737
 
        XTThreadPtr self = xt_get_self();
738
 
        int                     r;
739
 
 
740
 
        ASSERT_NS(rwlock->rw_init == 67890);
741
 
        r = pthread_rwlock_trywrlock(&rwlock->rw_plock);
742
 
        if (r == 0) {
743
 
                ASSERT_NS(!rwlock->rw_locker);
744
 
                rwlock->rw_locker = self;
745
 
#ifdef XT_THREAD_LOCK_INFO
746
 
                xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
747
 
#endif
748
 
        }
749
 
        return r == 0;
750
 
}
751
 
 
752
 
xtPublic int xt_p_rwlock_unlock(xt_rwlock_type *rwlock)
753
 
{
754
 
        XTThreadPtr self = xt_get_self();
755
 
 
756
 
        ASSERT_NS(rwlock->rw_init == 67890);
757
 
        if (rwlock->rw_locker) {
758
 
                ASSERT_NS(rwlock->rw_locker == self);
759
 
                rwlock->rw_locker = NULL;
760
 
        }
761
 
#ifdef XT_THREAD_LOCK_INFO
762
 
        xt_thread_lock_info_release_owner(&rwlock->rw_lock_info);
763
 
#endif
764
 
        return pthread_rwlock_unlock(&rwlock->rw_plock);
765
 
}
766
 
 
767
 
xtPublic int xt_p_rwlock_destroy(xt_rwlock_type *rwlock)
768
 
{
769
 
        ASSERT_NS(rwlock->rw_init == 67890);
770
 
        rwlock->rw_init = 0;
771
 
#ifdef XT_THREAD_LOCK_INFO
772
 
        xt_thread_lock_info_free(&rwlock->rw_lock_info);
773
 
#endif
774
 
        return pthread_rwlock_destroy(&rwlock->rw_plock);
775
 
}
776
 
 
777
 
#ifdef XT_THREAD_LOCK_INFO
778
 
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwlock, const pthread_rwlockattr_t *attr, const char *n)
779
 
#else
780
 
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwlock, const pthread_rwlockattr_t *attr)
781
 
#endif
782
 
{
783
 
        rwlock->rw_init = 67890;
784
 
        rwlock->rw_readers = 0;
785
 
        rwlock->rw_locker = NULL;
786
 
#ifdef XT_THREAD_LOCK_INFO
787
 
        rwlock->rw_name = n;
788
 
        xt_thread_lock_info_init(&rwlock->rw_lock_info, rwlock);
789
 
#endif
790
 
        return pthread_rwlock_init(&rwlock->rw_plock, attr);
791
 
}
792
 
 
793
 
#endif // DEBUG_LOCKING
794
 
 
795
 
#endif // XT_WIN
796