aed6766f2defca22d91e4032488a164c08ddb8b4
[synfig.git] / ETL / tags / stable / ETL / _mutex_pthreads.h
1 /*! ========================================================================
2 ** Extended Template and Library
3 ** Mutex Abstraction Class Implementation
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
12 **
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
22 **
23 ** ========================================================================= */
24
25 /* === S T A R T =========================================================== */
26
27 #ifndef __ETL__MUTEX_PTHREADS_H_
28 #define __ETL__MUTEX_PTHREADS_H_
29
30 /* === H E A D E R S ======================================================= */
31
32 #define __USE_GNU
33
34 #include <pthread.h>
35
36 #ifdef HAVE_SCHED_H
37 # include <sched.h>
38 #endif
39
40 /* === M A C R O S ========================================================= */
41
42 /* === C L A S S E S & S T R U C T S ======================================= */
43
44 _ETL_BEGIN_NAMESPACE
45
46 class mutex
47 {
48         pthread_mutex_t mtx;
49         pthread_t locker;
50         int depth;
51 public:
52
53         mutex()
54         {
55                 pthread_mutexattr_t attr;
56                 pthread_mutexattr_init(&attr);
57                 //#ifdef PTHREAD_PRIO_INHERIT
58                 //pthread_mutexattr_setprioceiling(&attr,PTHREAD_PRIO_INHERIT);
59                 //#endif
60                 #ifdef PTHREAD_MUTEX_RECURSIVE
61                 pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
62                 #endif
63                 pthread_mutex_init(&mtx,&attr);
64                 pthread_mutexattr_destroy(&attr);
65                 locker=0;
66                 depth=0;
67         }
68
69         ~mutex()
70         { pthread_mutex_destroy(&mtx); }
71
72
73         //! Exception-safe mutex lock class
74         class lock
75         {
76                 mutex *_mtx;
77         public:
78                 lock(mutex &x):_mtx(&x) { _mtx->lock_mutex(); }
79                 ~lock() { _mtx->unlock_mutex(); }
80                 mutex &get() { return *_mtx; }
81         };
82
83         void lock_mutex(void)
84         {
85                 if(!locker || locker!=pthread_self())
86                 {
87                         pthread_mutex_lock(&mtx);
88                         locker=pthread_self();
89                         depth=0;
90                         return;
91                 }
92                 depth++;
93         }
94
95         bool try_lock_mutex(void)
96         { return !(bool) pthread_mutex_trylock(&mtx); }
97
98         void unlock_mutex(void)
99         {
100                 if(depth)
101                 {
102                         depth--;
103                         return;
104                 }
105                 pthread_mutex_unlock(&mtx);
106                 locker=0;
107         }
108 };
109
110 _ETL_END_NAMESPACE
111
112 /* === E X T E R N S ======================================================= */
113
114 /* === E N D =============================================================== */
115
116 #endif