~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

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