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

Last change on this file since 231 was 231, checked in by garonne, 18 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.