Orfeo Toolbox  4.0
itkThreadLogger.cxx
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #include <iostream>
19 #include "itkThreadLogger.h"
20 #include "itksys/SystemTools.hxx"
21 
22 namespace itk
23 {
24 
27 {
28  this->m_Delay = 300; // ms
29  this->m_Threader = MultiThreader::New();
30  this->m_ThreadID = this->m_Threader->SpawnThread(ThreadFunction, this);
31 }
32 
35 {
36  if( this->m_Threader )
37  {
38  this->m_Threader->TerminateThread(this->m_ThreadID);
39  }
40 }
41 
42 void
45 {
46  this->m_Mutex.Lock();
47  this->m_OperationQ.push(SET_PRIORITY_LEVEL);
48  this->m_LevelQ.push(level);
49  this->m_Mutex.Unlock();
50 }
51 
55 {
56  this->m_Mutex.Lock();
57  PriorityLevelType level = this->m_PriorityLevel;
58  this->m_Mutex.Unlock();
59  return level;
60 }
61 
62 void
65 {
66  this->m_Mutex.Lock();
67  this->m_LevelForFlushing = level;
68  this->m_OperationQ.push(SET_LEVEL_FOR_FLUSHING);
69  this->m_LevelQ.push(level);
70  this->m_Mutex.Unlock();
71 }
72 
76 {
77  this->m_Mutex.Lock();
78  PriorityLevelType level = this->m_LevelForFlushing;
79  this->m_Mutex.Unlock();
80  return level;
81 }
82 
83 void
86 {
87  this->m_Mutex.Lock();
88  this->m_Delay = delay;
89  this->m_Mutex.Unlock();
90 }
91 
94 ::GetDelay() const
95 {
96  this->m_Mutex.Lock();
97  DelayType delay = this->m_Delay;
98  this->m_Mutex.Unlock();
99  return delay;
100 }
101 
102 void
105 {
106  this->m_Mutex.Lock();
107  this->m_OperationQ.push(ADD_LOG_OUTPUT);
108  this->m_OutputQ.push(output);
109  this->m_Mutex.Unlock();
110 }
111 
112 void
114 ::Write(PriorityLevelType level, std::string const & content)
115 {
116  this->m_Mutex.Lock();
117  this->m_OperationQ.push(WRITE);
118  this->m_MessageQ.push(content);
119  this->m_LevelQ.push(level);
120  this->m_Mutex.Unlock();
121  if ( this->m_LevelForFlushing >= level )
122  {
123  this->InternalFlush();
124  }
125 }
126 
127 void
130 {
131  this->m_Mutex.Lock();
132  this->m_OperationQ.push(FLUSH);
133  this->m_Mutex.Unlock();
134  this->InternalFlush();
135 }
136 
137 void
140 {
141  this->m_Mutex.Lock();
142 
143  while ( !this->m_OperationQ.empty() )
144  {
145  switch ( this->m_OperationQ.front() )
146  {
148  this->m_PriorityLevel = this->m_LevelQ.front();
149  this->m_LevelQ.pop();
150  break;
151 
153  this->m_LevelForFlushing = this->m_LevelQ.front();
154  this->m_LevelQ.pop();
155  break;
156 
158  this->m_Output->AddLogOutput( this->m_OutputQ.front() );
159  this->m_OutputQ.pop();
160  break;
161 
162  case ThreadLogger::WRITE:
163  this->Logger::Write( this->m_LevelQ.front(), this->m_MessageQ.front() );
164  this->m_LevelQ.pop();
165  this->m_MessageQ.pop();
166  break;
167  case ThreadLogger::FLUSH:
168  this->Logger::Flush();
169  break;
170  }
171  this->m_OperationQ.pop();
172  }
173  this->m_Output->Flush();
174  this->m_Mutex.Unlock();
175 }
176 
179 ::ThreadFunction(void *pInfoStruct)
180 {
181  struct MultiThreader:: ThreadInfoStruct *pInfo = (struct MultiThreader::ThreadInfoStruct *)pInfoStruct;
182 
183  if ( pInfo == NULL )
184  {
186  }
187 
188  if ( pInfo->UserData == NULL )
189  {
191  }
192 
193  ThreadLogger *pLogger = (ThreadLogger *)pInfo->UserData;
194 
195  while ( 1 )
196  {
197 
198 
199  pInfo->ActiveFlagLock->Lock();
200  int activeFlag = *pInfo->ActiveFlag;
201  pInfo->ActiveFlagLock->Unlock();
202  if ( !activeFlag )
203  {
204  break;
205  }
206 
207  pLogger->m_Mutex.Lock();
208  while ( !pLogger->m_OperationQ.empty() )
209  {
210  switch ( pLogger->m_OperationQ.front() )
211  {
213  pLogger->m_PriorityLevel = pLogger->m_LevelQ.front();
214  pLogger->m_LevelQ.pop();
215  break;
216 
218  pLogger->m_LevelForFlushing = pLogger->m_LevelQ.front();
219  pLogger->m_LevelQ.pop();
220  break;
221 
223  pLogger->m_Output->AddLogOutput( pLogger->m_OutputQ.front() );
224  pLogger->m_OutputQ.pop();
225  break;
226 
227  case ThreadLogger::WRITE:
228  pLogger->Logger::Write( pLogger->m_LevelQ.front(), pLogger->m_MessageQ.front() );
229  pLogger->m_LevelQ.pop();
230  pLogger->m_MessageQ.pop();
231  break;
232  case ThreadLogger::FLUSH:
233  pLogger->Logger::Flush();
234  break;
235  }
236  pLogger->m_OperationQ.pop();
237  }
238  pLogger->m_Mutex.Unlock();
239  itksys::SystemTools::Delay(pLogger->GetDelay());
240  }
242 }
243 
244 void
246 ::PrintSelf(std::ostream & os, Indent indent) const
247 {
248  Superclass::PrintSelf(os, indent);
249 
250  os << indent << "Thread ID: " << this->m_ThreadID << std::endl;
251  os << indent << "Low-priority Message Delay: " << this->m_Delay << std::endl;
252  os << indent << "Operation Queue Size: " << this->m_OperationQ.size() << std::endl;
253  os << indent << "Message Queue Size: " << this->m_MessageQ.size() << std::endl;
254  os << indent << "Level Queue Size: " << this->m_LevelQ.size() << std::endl;
255  os << indent << "Output Queue Size: " << this->m_OutputQ.size() << std::endl;
256 }
257 
258 } // namespace itk

Generated at Sat Mar 8 2014 15:37:34 for Orfeo Toolbox with doxygen 1.8.3.1