CLAM-Development  1.4.0
Thread.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "Thread.hxx"
23 #include "Mutex.hxx"
24 #include "xtime.hxx"
25 #include "Assert.hxx"
26 #include <sched.h>
27 #ifndef WIN32
28 #include <cstdio>
29 #endif
30 #ifdef WIN32
31 #include "CLAM_windows.h"
32 #undef GetClassName
33 #endif
34 
35 typedef void *(*pthread_start_pfunc) (void *);
36 
37 typedef void (*pthread_clean_pfunc) (void *);
38 
39 namespace CLAM
40 {
41 
42 Thread::Thread(bool realtime):
43  mRealtime(realtime),
44  mHasCode( false ),
45  mHasCleanup( false ),
46  mIsCancelled(false),
47  mRunning(false)
48 {
49 }
50 
52 {
53  if ( mRunning )
54  Stop();
55 }
56 
58 {
59  #ifdef WIN32
60  BOOL res;
61  DWORD err;
62 
63  res = SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS );
64  err = GetLastError();
65  res = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL );
66  err = GetLastError();
67  #else
68  if (mRealtime)
69  {
70  struct sched_param sched_param;
71  int policy;
72 
73  if (pthread_getschedparam(pthread_self(), &policy, &sched_param) < 0) {
74  printf("Scheduler getparam failed...\n");
75  }
76  sched_param.sched_priority = sched_get_priority_max(SCHED_RR)-1;
77  if (!pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param)) {
78  printf("Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
79  }
80  }else{
81  struct sched_param sched_param;
82  int policy;
83 
84  if (pthread_getschedparam(pthread_self(), &policy, &sched_param) < 0) {
85  printf("Scheduler getparam failed...\n");
86  }
87  sched_param.sched_priority = sched_get_priority_max(policy)/2;
88  pthread_setschedparam(pthread_self(), policy, &sched_param);
89  }
90  #endif
91 }
92 
94 {
95  CLAM_ASSERT( mHasCode, "The thread has no code to execute!" );
96 
97  mRunning = true;
98  pthread_create(&mThreadID, NULL, (pthread_start_pfunc)LaunchThread, this );
99 }
100 
102 {
103  LaunchThreadCleanup(this);
104  mIsCancelled = true;
105  mIsCancelled = false;
106  mRunning = false;
107 }
108 
110 {
111  int ret;
112  ret = sched_yield();
113 
114  CLAM_ASSERT( ret == 0, "The thread cannot yield?!!" );
115 }
116 
117 void Thread::SetThreadCode( const CBL::Functor0& thread_code )
118 {
119  mThreadCode = thread_code;
120  mHasCode = true;
121 }
122 
123 void Thread::SetCleanupCode( const CBL::Functor0& cleanup_code )
124 {
125  mCleanUpCode = cleanup_code;
126  mHasCleanup = true;
127 }
128 
129 void* Thread::LaunchThread( void* pvoid )
130 {
131  Thread* pSelf = (Thread*)pvoid;
132 
133  pSelf->mRunning=true;
134  pSelf->SetupPriorityPolicy();
135  pSelf->mThreadCode();
136  pSelf->mRunning = false;
137  pthread_exit(NULL);
138 
139  return NULL;
140 }
141 
142 void Thread::LaunchThreadCleanup( void* pvoid )
143 {
144  Thread* pSelf = (Thread*)pvoid;
145  if ( pSelf->mHasCleanup )
146  pSelf->mCleanUpCode();
147 
148  pthread_join( pSelf->mThreadID, NULL );
149 }
150 
151 void Thread::Sleep( unsigned int milliseconds )
152 {
153  SleepDetail( milliseconds );
154 }
155 
157 {
158  SleepDetail( 31536000 ); // 1 year
159 }
160 
161 void Thread::SleepDetail( unsigned int milliseconds)
162 {
163 
164  xtime xt;
165 
166  to_time( milliseconds, xt );
167 
168  Mutex aMutex;
169 
170  Mutex::ScopedLock lock( aMutex );
171 
172  mSleepCondition.TimedWait( lock, xt );
173 
174 }
175 
177 {
178  Mutex localMutex;
179 
180  Mutex::ScopedLock lock( localMutex );
181 
183 }
184 
185 }
186