KWStyle - itkLoggerThreadWrapper.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkLoggerThreadWrapper.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:41 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 #ifndef __itkLoggerThreadWrapper_txx
18 #define __itkLoggerThreadWrapper_txx
19 LEN #if ! ( defined(_MSC_VER)  ||   (defined(__GNUC__) && (__GNUC__ <= 2) ))//NOTE: This class does not work under MSVS6, or gnu 2.95
20
21 #include<iostream>
22 #include "itkLoggerThreadWrapper.h"
23
24
25 namespace itk
26 {
27
28 /** Set the priority level for the current logger. Only messages that have
29  * priorities equal or greater than the one set here will be posted to the
30  * current outputs */
31 template < class SimpleLoggerType >
32 LEN void LoggerThreadWrapper<SimpleLoggerType>::SetPriorityLevel( PriorityLevelType level )
33 {
34   this->m_WaitMutex.Unlock();
35   this->m_Mutex.Lock();
36   this->m_OperationQ.push(SET_PRIORITY_LEVEL);
37   this->m_LevelQ.push(level);
38   this->m_Mutex.Unlock();
39   this->m_WaitMutex.Lock();
40 }
41
42 /** Get the priority level for the current logger. Only messages that have
43  * priorities equal or greater than the one set here will be posted to the
44  * current outputs */
45 template < class SimpleLoggerType >
46 LEN typename SimpleLoggerType::PriorityLevelType LoggerThreadWrapper<SimpleLoggerType>::GetPriorityLevel() const
47 {
48   this->m_Mutex.Lock();
49   PriorityLevelType level = this->m_PriorityLevel;
50   this->m_Mutex.Unlock();
51   return level;
52 }
53
54 template < class SimpleLoggerType >
55 LEN void LoggerThreadWrapper<SimpleLoggerType>::SetLevelForFlushing( PriorityLevelType level )
56 {
57   this->m_WaitMutex.Unlock();
58   this->m_Mutex.Lock();
59   this->m_LevelForFlushing = level;
60   this->m_OperationQ.push(SET_LEVEL_FOR_FLUSHING);
61   this->m_LevelQ.push(level);
62   this->m_Mutex.Unlock();
63   this->m_WaitMutex.Lock();
64 }
65
66 template < class SimpleLoggerType >
67 LEN typename SimpleLoggerType::PriorityLevelType LoggerThreadWrapper<SimpleLoggerType>::GetLevelForFlushing() const
68 {
69   this->m_Mutex.Lock();
70   PriorityLevelType level = this->m_LevelForFlushing;
71   this->m_Mutex.Unlock();
72   return level;
73 }
74
75 /** Adds an output stream to the MultipleLogOutput for writing. */
76 template < class SimpleLoggerType >
77 void LoggerThreadWrapper<SimpleLoggerType>::AddLogOutput( OutputType* output )
78 {
79   this->m_WaitMutex.Unlock();
80   this->m_Mutex.Lock();
81   this->m_OperationQ.push(ADD_LOG_OUTPUT);
82   this->m_OutputQ.push(output);
83   this->m_Mutex.Unlock();
84   this->m_WaitMutex.Lock();
85 }
86
87 template < class SimpleLoggerType >
88 LEN void LoggerThreadWrapper<SimpleLoggerType>::Write(PriorityLevelType level, std::string const & content)
89 {
90   this->m_WaitMutex.Unlock();
91   this->m_Mutex.Lock();
92   if( this->m_PriorityLevel >= level )
93     {
94     this->m_OperationQ.push(WRITE);
95     this->m_MessageQ.push(content);
96     this->m_LevelQ.push(level);
97     }
98   this->m_Mutex.Unlock();
99   if( this->m_LevelForFlushing >= level )
100     {
101     this->Flush();
102     }
103   this->m_WaitMutex.Lock();
104 }
105
106 template < class SimpleLoggerType >
107 void LoggerThreadWrapper<SimpleLoggerType>::Flush()
108 {
109   this->m_Mutex.Lock();
110
111 IND ****while( !this->m_OperationQ.empty() )
112     {
113 IND ******switch( this->m_OperationQ.front() )
114       {
115       case Self::SET_PRIORITY_LEVEL:
116 IND ********this->m_PriorityLevel = this->m_LevelQ.front();
117 IND ********this->m_LevelQ.pop();
118 IND ********break;
119
120       case Self::SET_LEVEL_FOR_FLUSHING:
121 IND ********this->m_LevelForFlushing = this->m_LevelQ.front();
122 IND ********this->m_LevelQ.pop();
123 IND ********break;
124
125       case Self::ADD_LOG_OUTPUT:
126 IND ********this->m_Output->AddLogOutput(this->m_OutputQ.front());
127 IND ********this->m_OutputQ.pop();
128 IND ********break;
129
130       case Self::WRITE:
131 LEN,IND ********this->SimpleLoggerType::Write(this->m_LevelQ.front(), this->m_MessageQ.front());
132 IND ********this->m_LevelQ.pop();
133 IND ********this->m_MessageQ.pop();
134 IND ********break;
135       case Self::FLUSH:
136 IND ********this->SimpleLoggerType::Flush();
137 IND ********break;
138       }
139 IND ******this->m_OperationQ.pop();
140     }
141 IND ****this->m_Output->Flush();
142   this->m_Mutex.Unlock();
143 }
144
145
146 /** Constructor */
147 template < class SimpleLoggerType >
148 LoggerThreadWrapper<SimpleLoggerType>::LoggerThreadWrapper()
149 {
150   this->m_WaitMutex.Lock();
151   this->m_Threader = MultiThreader::New();
152   this->m_ThreadID = this->m_Threader->SpawnThread(ThreadFunction, this);
153 }
154
155
156 /** Destructor */
157 template < class SimpleLoggerType >
158 LoggerThreadWrapper<SimpleLoggerType>::~LoggerThreadWrapper()
159 {
160   this->Flush();
161   this->m_WaitMutex.Unlock();
162   if( this->m_Threader )
163 IND **{
164     this->m_Threader->TerminateThread(this->m_ThreadID);
165 IND **}
166 }
167
168
169 template < class SimpleLoggerType >
170 LEN ITK_THREAD_RETURN_TYPE LoggerThreadWrapper<SimpleLoggerType>::ThreadFunction(void* pInfoStruct)
171 {
172 LEN   struct MultiThreader::ThreadInfoStruct * pInfo = (struct MultiThreader::ThreadInfoStruct*)pInfoStruct;
173
174   if( pInfo == NULL )
175 IND **{
176     return ITK_THREAD_RETURN_VALUE;
177 IND **}
178
179   if( pInfo->UserData == NULL )
180 IND **{
181     return ITK_THREAD_RETURN_VALUE;
182 IND **}
183
184   LoggerThreadWrapper *pLogger = (LoggerThreadWrapper*)pInfo->UserData;
185
186   while(1)
187 IND **{
188
189     pLogger->m_WaitMutex.Lock();
190
191     pInfo->ActiveFlagLock->Lock();
192     int activeFlag = *pInfo->ActiveFlag;
193     pInfo->ActiveFlagLock->Unlock();
194     if( !activeFlag )
195 IND ****{
196       break;
197 IND ****}
198
199     pLogger->m_Mutex.Lock();
200     while( !pLogger->m_OperationQ.empty() )
201 IND ****{
202       switch( pLogger->m_OperationQ.front() )
203 IND ******{
204 IND ******case Self::SET_PRIORITY_LEVEL:
205         pLogger->m_PriorityLevel = pLogger->m_LevelQ.front();
206         pLogger->m_LevelQ.pop();
207         break;
208
209 IND ******case Self::SET_LEVEL_FOR_FLUSHING:
210         pLogger->m_LevelForFlushing = pLogger->m_LevelQ.front();
211         pLogger->m_LevelQ.pop();
212         break;
213
214 IND ******case Self::ADD_LOG_OUTPUT:
215         pLogger->m_Output->AddLogOutput(pLogger->m_OutputQ.front());
216         pLogger->m_OutputQ.pop();
217         break;
218
219 IND ******case Self::WRITE:
220 LEN         pLogger->SimpleLoggerType::Write(pLogger->m_LevelQ.front(), pLogger->m_MessageQ.front());
221         pLogger->m_LevelQ.pop();
222         pLogger->m_MessageQ.pop();
223         break;
224 IND ******case Self::FLUSH:
225         pLogger->SimpleLoggerType::Flush();
226         break;
227 IND ******}
228       pLogger->m_OperationQ.pop();
229 IND ****}
230     pLogger->m_Mutex.Unlock();
231     pLogger->m_WaitMutex.Unlock();
232 IND **}
233   return ITK_THREAD_RETURN_VALUE;
234 }
235
236
237 /** Print contents of a LoggerThreadWrapper */
238 template < class SimpleLoggerType >
239 LEN void LoggerThreadWrapper<SimpleLoggerType>::PrintSelf(std::ostream &os, Indent indent) const
240 {
241   Superclass::PrintSelf(os,indent);
242
243   os << indent << "Thread ID: " << this->m_ThreadID << std::endl;
244 LEN   os << indent << "Operation Queue Size: " << this->m_OperationQ.size() << std::endl;
245 LEN   os << indent << "Message Queue Size: " << this->m_MessageQ.size() << std::endl;
246   os << indent << "Level Queue Size: " << this->m_LevelQ.size() << std::endl;
247   os << indent << "Output Queue Size: " << this->m_OutputQ.size() << std::endl;
248 }
249
250
251 // namespace itk
252
253 #endif  // !defined (_MSC_VER)
254 #endif
255

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:20PM
© Kitware Inc.