KWStyle - itkThreadLogger.cxx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkThreadLogger.cxx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:48 $
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 DEF =========================================================================*/
17
18 #include<iostream>
19 #include "itkThreadLogger.h"
20
21
22 namespace itk
23 {
24
25 /** Set the priority level for the current logger. Only messages that have
26  * priorities equal or greater than the one set here will be posted to the
27  * current outputs */
28 void ThreadLogger::SetPriorityLevel( PriorityLevelType level )
29 {
30   this->m_WaitMutex.Unlock();
31   this->m_Mutex.Lock();
32   this->m_OperationQ.push(SET_PRIORITY_LEVEL);
33   this->m_LevelQ.push(level);
34   this->m_Mutex.Unlock();
35   this->m_WaitMutex.Lock();
36 }
37
38 /** Get the priority level for the current logger. Only messages that have
39  * priorities equal or greater than the one set here will be posted to the
40  * current outputs */
41 Logger::PriorityLevelType ThreadLogger::GetPriorityLevel() const
42 {
43   this->m_Mutex.Lock();
44   PriorityLevelType level = this->m_PriorityLevel;
45   this->m_Mutex.Unlock();
46   return level;
47 }
48
49 void ThreadLogger::SetLevelForFlushing( PriorityLevelType level )
50 {
51   this->m_WaitMutex.Unlock();
52   this->m_Mutex.Lock();
53   this->m_LevelForFlushing = level;
54   this->m_OperationQ.push(SET_LEVEL_FOR_FLUSHING);
55   this->m_LevelQ.push(level);
56   this->m_Mutex.Unlock();
57   this->m_WaitMutex.Lock();
58 }
59
60 Logger::PriorityLevelType ThreadLogger::GetLevelForFlushing() const
61 {
62   this->m_Mutex.Lock();
63   PriorityLevelType level = this->m_LevelForFlushing;
64   this->m_Mutex.Unlock();
65   return level;
66 }
67
68 /** Adds an output stream to the MultipleLogOutput for writing. */
69 void ThreadLogger::AddLogOutput( OutputType* output )
70 {
71   this->m_WaitMutex.Unlock();
72   this->m_Mutex.Lock();
73   this->m_OperationQ.push(ADD_LOG_OUTPUT);
74   this->m_OutputQ.push(output);
75   this->m_Mutex.Unlock();
76   this->m_WaitMutex.Lock();
77 }
78
79 void ThreadLogger::Write(PriorityLevelType level, std::string const & content)
80 {
81   this->m_WaitMutex.Unlock();
82   this->m_Mutex.Lock();
83   this->m_OperationQ.push(WRITE);
84   this->m_MessageQ.push(content);
85   this->m_LevelQ.push(level);
86   this->m_Mutex.Unlock();
87   this->m_WaitMutex.Lock();
88 }
89
90
91 void ThreadLogger::Flush()
92 {
93   this->m_Mutex.Lock();
94
95 IND ****while( !this->m_OperationQ.empty() )
96     {
97 IND ******switch( this->m_OperationQ.front() )
98       {
99       case ThreadLogger::SET_PRIORITY_LEVEL:
100 IND ********this->m_PriorityLevel = this->m_LevelQ.front();
101 IND ********this->m_LevelQ.pop();
102 IND ********break;
103
104       case ThreadLogger::SET_LEVEL_FOR_FLUSHING:
105 IND ********this->m_LevelForFlushing = this->m_LevelQ.front();
106 IND ********this->m_LevelQ.pop();
107 IND ********break;
108
109       case ThreadLogger::ADD_LOG_OUTPUT:
110 IND ********this->m_Output->AddLogOutput(this->m_OutputQ.front());
111 IND ********this->m_OutputQ.pop();
112 IND ********break;
113
114       case ThreadLogger::WRITE:
115 IND ********this->Logger::Write(this->m_LevelQ.front(), this->m_MessageQ.front());
116 IND ********this->m_LevelQ.pop();
117 IND ********this->m_MessageQ.pop();
118 IND ********break;
119       case ThreadLogger::FLUSH:
120 IND ********this->Logger::Flush();
121 IND ********break;
122       }
123 IND ******this->m_OperationQ.pop();
124     }
125 IND ****this->m_Output->Flush();
126   this->m_Mutex.Unlock();
127
128 }
129
130
131 /** Constructor */
132 ThreadLogger::ThreadLogger()
133 {
134   this->m_WaitMutex.Lock();
135   this->m_Threader = MultiThreader::New();
136   this->m_ThreadID = this->m_Threader->SpawnThread(ThreadFunction, this);
137 }
138
139
140 /** Destructor */
141 ThreadLogger::~ThreadLogger()
142 {
143   this->m_WaitMutex.Unlock();
144   if( this->m_Threader )
145 IND **{
146     this->m_Threader->TerminateThread(this->m_ThreadID);
147 IND **}
148 }
149
150
151 ITK_THREAD_RETURN_TYPE ThreadLogger::ThreadFunction(void* pInfoStruct)
152 {
153 LEN   struct MultiThreader::ThreadInfoStruct * pInfo = (struct MultiThreader::ThreadInfoStruct*)pInfoStruct;
154
155   if( pInfo == NULL )
156 IND **{
157     return ITK_THREAD_RETURN_VALUE;
158 IND **}
159
160   if( pInfo->UserData == NULL )
161 IND **{
162     return ITK_THREAD_RETURN_VALUE;
163 IND **}
164
165   ThreadLogger *pLogger = (ThreadLogger*)pInfo->UserData;
166
167   while(1)
168 IND **{
169     
170     pLogger->m_WaitMutex.Lock();
171
172     pInfo->ActiveFlagLock->Lock();
173     int activeFlag = *pInfo->ActiveFlag;
174     pInfo->ActiveFlagLock->Unlock();
175     if( !activeFlag )
176 IND ****{
177       break;
178 IND ****}
179     
180     pLogger->m_Mutex.Lock();
181     while( !pLogger->m_OperationQ.empty() )
182 IND ****{
183       switch( pLogger->m_OperationQ.front() )
184 IND ******{
185 IND ******case ThreadLogger::SET_PRIORITY_LEVEL:
186         pLogger->m_PriorityLevel = pLogger->m_LevelQ.front();
187         pLogger->m_LevelQ.pop();
188         break;
189
190 IND ******case ThreadLogger::SET_LEVEL_FOR_FLUSHING:
191         pLogger->m_LevelForFlushing = pLogger->m_LevelQ.front();
192         pLogger->m_LevelQ.pop();
193         break;
194
195 IND ******case ThreadLogger::ADD_LOG_OUTPUT:
196         pLogger->m_Output->AddLogOutput(pLogger->m_OutputQ.front());
197         pLogger->m_OutputQ.pop();
198         break;
199
200 IND ******case ThreadLogger::WRITE:
201 LEN         pLogger->Logger::Write(pLogger->m_LevelQ.front(), pLogger->m_MessageQ.front());
202         pLogger->m_LevelQ.pop();
203         pLogger->m_MessageQ.pop();
204         break;
205 IND ******case ThreadLogger::FLUSH:
206         pLogger->Logger::Flush();
207         break;
208 IND ******}
209       pLogger->m_OperationQ.pop();
210 IND ****}
211     pLogger->m_Mutex.Unlock();
212     pLogger->m_WaitMutex.Unlock();
213 IND **}
214   return ITK_THREAD_RETURN_VALUE;
215 }
216
217
218 /** Print contents of a ThreadLogger */
219 void ThreadLogger::PrintSelf(std::ostream &os, Indent indent) const
220 {
221   Superclass::PrintSelf(os,indent);
222   
223   os << indent << "Thread ID: " << this->m_ThreadID << std::endl;
224 LEN   os << indent << "Operation Queue Size: " << this->m_OperationQ.size() << std::endl;
225 LEN   os << indent << "Message Queue Size: " << this->m_MessageQ.size() << std::endl;
226   os << indent << "Level Queue Size: " << this->m_LevelQ.size() << std::endl;
227   os << indent << "Output Queue Size: " << this->m_OutputQ.size() << std::endl;
228 }
229
230
231 // namespace itk
232
233 EOF

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