source: tbroadcast/v1/src/TCmThread.cxx@ 517

Last change on this file since 517 was 231, checked in by garonne, 19 years ago

import tbroadcast

File size: 11.5 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3
4#include <iostream.h>
5#include <pthread.h>
6#include <signal.h>
7#include <sys/time.h>
8
9#include "TCmThread.hxx"
10
11#include <vector>
12
13#include <time.h>
14#include <unistd.h>
15
16
17//-------------------------------------------------------
18//
19// Threads
20//
21//-------------------------------------------------------
22
23typedef void* (*pthread_function_t) (void*);
24
25static int DebugLevel = 0;
26
27//-------------------------------------------------------
28void TCmThread::set_debug_level (int level)
29//-------------------------------------------------------
30{
31 DebugLevel = level;
32}
33
34//-------------------------------------------------------
35int TCmThread::debug_level ()
36//-------------------------------------------------------
37{
38 return (DebugLevel);
39}
40
41//-------------------------------------------------------
42TCmThread::TCmThread ()
43//-------------------------------------------------------
44{
45 _running = false;
46}
47
48//-------------------------------------------------------
49TCmThread::~TCmThread ()
50//-------------------------------------------------------
51{
52 void* value;
53 int status;
54
55 if (debug_level () > 0)
56 {
57 TCmMutex::iolock ();
58 std::cout << "~TCmThread> " << _thread_id << " running " << _running << std::endl;
59 TCmMutex::iounlock ();
60 }
61
62 if (_running)
63 {
64 status = pthread_kill ((pthread_t) _thread_id, SIGINT);
65
66 if (debug_level () > 0)
67 {
68 TCmMutex::iolock ();
69 std::cout << "~TCmThread> " << _thread_id << " status after kill=" << status << std::endl;
70 TCmMutex::iounlock ();
71 }
72
73 status = pthread_cancel ((pthread_t) _thread_id);
74
75 if (debug_level () > 0)
76 {
77 TCmMutex::iolock ();
78 std::cout << "~TCmThread> " << _thread_id << " status after cancel=" << status << std::endl;
79 TCmMutex::iounlock ();
80 }
81
82 status = pthread_join ((pthread_t) _thread_id, &value);
83
84 if (debug_level () > 0)
85 {
86 TCmMutex::iolock ();
87 std::cout << "~TCmThread> " << _thread_id << " status after join=" << status << std::endl;
88 TCmMutex::iounlock ();
89 }
90
91 }
92
93 status = pthread_detach ((pthread_t) _thread_id);
94
95 if (debug_level () > 0)
96 {
97 TCmMutex::iolock ();
98 std::cout << "~TCmThread> " << _thread_id << " status after detach=" << status << std::endl;
99 TCmMutex::iounlock ();
100 }
101
102 if (debug_level () > 0)
103 {
104 TCmMutex::iolock ();
105 std::cout << "~TCmThread> " << _thread_id << " finished " << std::endl;
106 TCmMutex::iounlock ();
107 }
108}
109
110//-------------------------------------------------------
111bool TCmThread::start ()
112//-------------------------------------------------------
113{
114 /*
115 On lance le thread qui fait fonctionner la fonction Run
116 */
117
118 if (debug_level () > 0)
119 {
120 TCmMutex::iolock ();
121 std::cout << "TCmThread::start> " << this << std::endl;
122 TCmMutex::iounlock ();
123 }
124
125#ifdef PTHREAD_USE_VALUE_ATTR
126 pthread_attr_t attr;
127 pthread_attr_create (&attr);
128
129 int status = pthread_create (&((pthread_t) _thread_id),
130 attr,
131 (pthread_function_t) run_it,
132 this);
133#else
134 int status = pthread_create (&((pthread_t) _thread_id),
135 NULL,
136 (pthread_function_t) run_it,
137 this);
138#endif
139
140 if (status != 0)
141 {
142 TCmMutex::iolock ();
143 std::cout << "TCmThread::start> status create = " << status << std::endl;
144 TCmMutex::iounlock ();
145 }
146
147 if (debug_level () > 0)
148 {
149 TCmMutex::iolock ();
150 std::cout << "TCmThread::start> " << _thread_id << " running " << _running << std::endl;
151 TCmMutex::iounlock ();
152 }
153
154 if (status == 0) return (true);
155 else return (false);
156}
157
158//-------------------------------------------------------
159bool TCmThread::stop ()
160//-------------------------------------------------------
161{
162 void* value;
163 int status;
164
165 if (debug_level () > 0)
166 {
167 TCmMutex::iolock ();
168 std::cout << "TCmThread::stop> " << _thread_id << " running " << _running << std::endl;
169 TCmMutex::iounlock ();
170 }
171
172 status = pthread_cancel ((pthread_t) _thread_id);
173 if (status == 0)
174 {
175 status = pthread_join ((pthread_t) _thread_id, &value);
176
177 if (status != 0)
178 {
179 TCmMutex::iolock ();
180 perror ("join error");
181 std::cout << "TCmThread::stop join error> " << _thread_id << " status=" << status << std::endl;
182 TCmMutex::iounlock ();
183 }
184
185 if (debug_level () > 0)
186 {
187 TCmMutex::iolock ();
188 std::cout << "TCmThread::stopped> " << _thread_id << " running " << _running << std::endl;
189 TCmMutex::iounlock ();
190 }
191
192 status = pthread_detach ((pthread_t) _thread_id);
193
194 if (status != 0)
195 {
196 TCmMutex::iolock ();
197 perror ("detach error");
198 std::cout << "TCmThread::stop detach error> " << _thread_id << " status=" << status << std::endl;
199 TCmMutex::iounlock ();
200 }
201
202 if (debug_level () > 0)
203 {
204 TCmMutex::iolock ();
205 std::cout << "TCmThread::stopped> " << _thread_id << " running " << _running << std::endl;
206 TCmMutex::iounlock ();
207 }
208
209 return ((status == 0));
210 }
211 else
212 {
213 //if (debug_level () > 0)
214 {
215 TCmMutex::iolock ();
216 perror ("cancel error");
217 std::cout << "TCmThread::stop cancel error> " << _thread_id << " status=" << status << std::endl;
218 TCmMutex::iounlock ();
219 }
220 return (false);
221 }
222}
223
224//-------------------------------------------------------
225void TCmThread::run ()
226//-------------------------------------------------------
227{
228 if (debug_level () > 0)
229 {
230 TCmMutex::iolock ();
231 std::cout << "TCmThread::run>" << std::endl;
232 TCmMutex::iounlock ();
233 }
234}
235
236//-------------------------------------------------------
237void TCmThread::cleanup ()
238//-------------------------------------------------------
239{
240 TCmMutex::iolock ();
241 std::cout << "TCmThread::cleanup>" << std::endl;
242 TCmMutex::iounlock ();
243}
244
245//-------------------------------------------------------
246void TCmThread::do_cleanup (void* thread)
247//-------------------------------------------------------
248{
249 if (thread != 0)
250 {
251 ((TCmThread*) thread)->cleanup ();
252 }
253}
254
255//-------------------------------------------------------
256void TCmThread::run_it (TCmThread* thread)
257//-------------------------------------------------------
258{
259 //int status = 0;
260 //pthread_cleanup_push (do_cleanup, thread);
261
262 thread->_thread_id = pthread_self ();
263 thread->_running = true;
264 thread->_should_die = false;
265
266 thread->run ();
267 thread->_running = false;
268
269 if (debug_level () > 0)
270 {
271 TCmMutex::iolock ();
272 std::cout << "TCmThread::finished> " << thread->_thread_id << std::endl;
273 TCmMutex::iounlock ();
274 }
275
276 pthread_detach (thread->_thread_id);
277
278 //if (thread->_should_die) delete (thread);
279
280 //pthread_exit (&status);
281 //pthread_cleanup_pop (0);
282
283 do_cleanup (thread);
284}
285
286//-------------------------------------------------------
287//
288// Mutex
289//
290//-------------------------------------------------------
291
292//-------------------------------------------------------
293TCmMutex::TCmMutex ()
294//-------------------------------------------------------
295{
296 initialize ();
297}
298
299//-------------------------------------------------------
300TCmMutex::TCmMutex (const std::string& info) : m_info (info)
301//-------------------------------------------------------
302{
303 initialize ();
304}
305
306//-------------------------------------------------------
307TCmMutex::~TCmMutex ()
308//-------------------------------------------------------
309{
310 pthread_mutex_t* mutex = (pthread_mutex_t*) _mutex;
311
312 int status = pthread_mutex_destroy (mutex);
313 if (status != 0)
314 {
315 std::cout << "Error in mutex_destroy " << _mutex << " status=" << status << std::endl;
316 }
317
318 delete mutex;
319}
320
321//-------------------------------------------------------
322void TCmMutex::set_info (const std::string& info)
323//-------------------------------------------------------
324{
325 m_info = info;
326}
327
328//-------------------------------------------------------
329std::string TCmMutex::show () const
330//-------------------------------------------------------
331{
332 std::string s;
333 char buff[20];
334
335 sprintf (buff, "%d", m_count);
336
337 s = m_info;
338 s += " ";
339 s += buff;
340
341 return (s);
342}
343
344//-------------------------------------------------------
345bool TCmMutex::trylock (const std::string& /*info*/)
346//-------------------------------------------------------
347{
348 int status;
349
350 status = pthread_mutex_trylock ((pthread_mutex_t*) _mutex);
351
352 if (status == 0)
353 {
354 m_count++;
355 return (true);
356 }
357 else return (false);
358}
359
360//-------------------------------------------------------
361void TCmMutex::lock (const std::string& info)
362//-------------------------------------------------------
363{
364 int status;
365
366 /*
367 int retries = 0;
368
369 for (retries = 0; retries < 1000000; retries++)
370 {
371 status = pthread_mutex_trylock ((pthread_mutex_t*) _mutex);
372
373 if (status == 0)
374 {
375 m_count++;
376 break;
377 }
378 else
379 {
380 if ((retries % 100000) == 0)
381 {
382 std::cout << "Error in lock " << _mutex << " " << m_info << " " << info << " " << m_context << " status=" << status << " " << retries << std::endl;
383 }
384 }
385 }
386
387 if (status != 0)
388 {
389 std::cout << "Final error in lock " << _mutex << " " << m_info << " " << info << " " << m_context << " status=" << status << std::endl;
390 exit (1);
391 }
392 else
393 {
394 m_context = info;
395 }
396 */
397
398 status = pthread_mutex_lock ((pthread_mutex_t*) _mutex);
399
400 if (status == 0)
401 {
402 m_count++;
403 //m_context = info;
404 }
405 else
406 {
407 std::cout << "Final error in lock " << _mutex << " " << m_info << " " << info << " " << m_context << " status=" << status << std::endl;
408 exit (1);
409 }
410}
411
412//-------------------------------------------------------
413void TCmMutex::unlock ()
414//-------------------------------------------------------
415{
416 //m_context = "";
417 m_count--;
418 int status = pthread_mutex_unlock ((pthread_mutex_t*) _mutex);
419 if (status != 0)
420 {
421 std::cout << "Error in unlock " << _mutex << " " << m_info << " status=" << status << std::endl;
422 }
423}
424
425//-------------------------------------------------------
426void TCmMutex::iolock ()
427//-------------------------------------------------------
428{
429 static TCmMutex& iolock = get_iolock ();
430
431 iolock.lock ("IO");
432}
433
434//-------------------------------------------------------
435void TCmMutex::iounlock ()
436//-------------------------------------------------------
437{
438 static TCmMutex& iolock = get_iolock ();
439
440 iolock.unlock ();
441}
442
443//-------------------------------------------------------
444TCmMutex& TCmMutex::get_iolock ()
445//-------------------------------------------------------
446{
447 static TCmMutex iolock ("iolock");
448
449 return (iolock);
450}
451
452//-------------------------------------------------------
453void TCmMutex::initialize ()
454//-------------------------------------------------------
455{
456 pthread_mutex_t* mutex = new pthread_mutex_t;
457 //pthread_mutexattr_t* attr = new pthread_mutexattr_t;
458
459 _mutex = (void*) mutex;
460 m_count = 0;
461
462 int status;
463
464 /*
465 status = pthread_mutexattr_init (attr);
466 if (status != 0)
467 {
468 std::cout << "Error in mutexattr_init " << attr << " status=" << status << std::endl;
469 }
470
471 status = pthread_mutexattr_settype (attr, PTHREAD_MUTEX_RECURSIVE_NP);
472 if (status != 0)
473 {
474 std::cout << "Error in mutexattr_settype " << attr << " status=" << status << std::endl;
475 }
476
477 status = pthread_mutex_init (mutex, attr);
478 */
479
480 status = pthread_mutex_init (mutex, 0);
481 if (status != 0)
482 {
483 std::cout << "Error in mutex_init " << _mutex << " " << m_info << " status=" << status << std::endl;
484 }
485}
486
Note: See TracBrowser for help on using the repository browser.