Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vsnet_thread_p.cpp
Go to the documentation of this file.
1 #include "vsnet_thread.h"
2 
3 #ifdef USE_PTHREAD
4 
5 #include "vsnet_debug.h"
6 
7 #include <pthread.h>
8 #include <stdio.h>
9 
10 /*------------------------------------------------------------*
11 * definition of VSThread *
12 *------------------------------------------------------------*/
13 
14 void VSThread::init()
15 {
16  //nothing to do
17 }
18 
19 static void * vs_thread_start( void *info )
20 {
21  ( (VSThread*) info )->run();
22  return NULL;
23 }
24 
25 struct VSThread::Private
26 {
27  bool detach;
28  pthread_attr_t ta;
29  pthread_t t;
30 };
31 
32 VSThread::VSThread( bool detached )
33 {
34  _internal = new Private;
35  _internal->detach = detached;
36 #if defined (_AIX)
37  ::pthread_init( &_internal->t );
38 #endif
39  ::pthread_attr_init( &_internal->ta );
40 }
41 
43 {
44  ::pthread_attr_destroy( &_internal->ta );
45  delete _internal;
46 }
47 
48 void VSThread::start()
49 {
50  int ret;
51  int err;
52  if (_internal->detach) {
53  ret = ::pthread_attr_setdetachstate( &_internal->ta,
54  PTHREAD_CREATE_DETACHED );
55  if (ret != 0)
56  perror( "pthread_attr_setdetachstate failed" );
57  }
58 #if !defined (_AIX)
59  ret = ::pthread_attr_setscope( &_internal->ta, PTHREAD_SCOPE_SYSTEM );
60  if (ret != 0)
61  perror( "pthread_attr_setscope failed" );
62  //signal( SIGRTMIN, SIG_DFL );
63 #endif
64 
65 #if defined (_AIX) && defined (_AIX32_THREADS)
66  //obsolete DCE thread API on AIX
67  err = ::pthread_create( &_internal->t,
68  _internal->ta,
69  vs_thread_start,
70  (void*) this );
71 #else
72  err = ::pthread_create( &_internal->t,
73  &_internal->ta,
74  vs_thread_start,
75  (void*) this );
76 #endif
77  if (err != 0)
78  perror( "pthread_create failed" );
79  //return false;
80  //return true;
81 }
82 
83 void VSThread::join()
84 {
85  if (_internal->detach == false)
86  ::pthread_join( _internal->t, NULL );
87 }
88 
89 /*------------------------------------------------------------*
90 * definition of VSMutex *
91 *------------------------------------------------------------*/
92 
93 struct VSMutex::Private
94 {
95 #if defined (linux) || defined (_AIX)
96  pthread_mutexattr_t attr;
97 #endif
98  pthread_mutex_t lck;
99 };
100 
102 {
103 #if defined (linux) || defined (_AIX)
104  _internal = new Private;
105  int ret = ::pthread_mutexattr_init( &_internal->attr );
106  if (ret != 0) {
107  perror( "pthread_mutexattr_init failed (ignored)" );
108  ret = ::pthread_mutex_init( &_internal->lck, NULL );
109  } else {
110  /* PTHREAD_MUTEX_DEFAULT - undefined behaviour
111  * PTHREAD_MUTEX_NORMAL - hang on double lock
112  * PTHREAD_MUTEX_ERRORCHECK - return an error on double lock
113  * PTHREAD_MUTEX_RECURSIVE - allow recursive locking (Not Windows
114  * semantics, this is a counter!)
115  */
116  #ifdef VSNET_DEBUG
117  ::pthread_mutexattr_settype( &_internal->attr, PTHREAD_MUTEX_ERRORCHECK );
118  #else
119  ::pthread_mutexattr_settype( &_internal->attr, PTHREAD_MUTEX_NORMAL );
120  #endif
121 
122  /* PTHREAD_PROCESS_PRIVATE - the default, mutex is not shared with
123  * another process
124  * PTHREAD_PROCESS_SHARED - mutex may be shared with another process
125  */
126  ::pthread_mutexattr_setpshared( &_internal->attr, PTHREAD_PROCESS_PRIVATE );
127 
128  ret = ::pthread_mutex_init( &_internal->lck, &_internal->attr );
129  }
130  if (ret != 0)
131  perror( "pthread_mutex_init failed" );
132 #else /*linux||_AIX*/
133  _internal = new Private;
134  int ret = ::pthread_mutex_init( &_internal->lck, NULL );
135  if (ret != 0)
136  perror( "pthread_mutex_init failed" );
137 #endif /*linux||_AIX*/
138 }
139 
141 {
142  int ret = ::pthread_mutex_destroy( &_internal->lck );
143  if (ret != 0)
144  perror( "pthread_mutex_destroy failed" );
145 #if defined (linux) || defined (_AIX)
146  ret = ::pthread_mutexattr_destroy( &_internal->attr );
147  if (ret != 0)
148  perror( "pthread_mutexattr_destroy failed" );
149 #endif
150  delete _internal;
151 }
152 
153 void VSMutex::lock()
154 {
155  int ret = ::pthread_mutex_lock( &_internal->lck );
156  if (ret != 0)
157  perror( "pthread_mutex_lock failed" );
158 }
159 
160 void VSMutex::unlock()
161 {
162  int ret = ::pthread_mutex_unlock( &_internal->lck );
163  if (ret != 0)
164  perror( "pthread_mutex_unlock failed" );
165 }
166 
167 /*------------------------------------------------------------*
168 * definition of VSCond *
169 *------------------------------------------------------------*/
170 
171 struct VSCond::Private
172 {
173  pthread_condattr_t attr;
174  pthread_cond_t ctr;
175 };
176 
178 {
179  _internal = new Private;
180  int ret = ::pthread_condattr_init( &_internal->attr );
181  if (ret != 0) {
182  perror( "pthread_condattr_init failed" );
183  } else {
184  ret = ::pthread_cond_init( &_internal->ctr, &_internal->attr );
185  if (ret != 0)
186  perror( "pthread_cond_init failed" );
187  }
188 }
189 
191 {
192  int ret = ::pthread_cond_destroy( &_internal->ctr );
193  if (ret != 0)
194  perror( "pthread_cond_destroy failed" );
195  ret = ::pthread_condattr_destroy( &_internal->attr );
196  if (ret != 0)
197  perror( "pthread_condattr_destroy failed" );
198  delete _internal;
199 }
200 
201 void VSCond::wait( VSMutex &mx )
202 {
203  int ret = ::pthread_cond_wait( &_internal->ctr, &mx._internal->lck );
204  if (ret != 0)
205  perror( "pthread_cond_wait failed" );
206 }
207 
208 void VSCond::signal()
209 {
210  int ret = ::pthread_cond_signal( &_internal->ctr );
211  if (ret != 0)
212  perror( "pthread_cond_signal failed" );
213 }
214 
215 void VSCond::broadcast()
216 {
217  int ret = ::pthread_cond_broadcast( &_internal->ctr );
218  if (ret != 0)
219  perror( "pthread_cond_broadcast failed" );
220 }
221 
222 #endif /* USE_PTHREAD */
223