Operator Console
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Member Functions | Static Public Member Functions | Protected Attributes | List of all members
StdoutThread Class Reference

Defines a thread class for capturing stdout. More...

#include <StdoutThread.h>

Inheritance diagram for StdoutThread:
[legend]

Public Member Functions

 StdoutThread (void)
 
virtual ~StdoutThread (void)
 
void Get (CString &dst, bool clear)
 
void Quit ()
 
bool InitThread (int bufLen, UINT threadMsg, DWORD parentID)
 
 StdoutThread (void)
 
virtual ~StdoutThread (void)
 
void Get (CString &dst, bool clear)
 
void Quit ()
 
bool InitThread (int bufLen, UINT threadMsg, DWORD parentID)
 
- Public Member Functions inherited from StdoutRedirect
 StdoutRedirect ()
 
virtual ~StdoutRedirect ()
 
void Close ()
 
int Init (int bufferSize)
 
int Start ()
 
int Stop ()
 
int GetBuffer (char *buffer, int size)
 
 StdoutRedirect ()
 
virtual ~StdoutRedirect ()
 
void Close ()
 
int Init (int bufferSize)
 
int Start ()
 
int Stop ()
 
int GetBuffer (char *buffer, int size)
 

Static Public Member Functions

static UINT __cdecl ThreadProc (void *param)
 
static UINT __cdecl ThreadProc (void *param)
 

Protected Attributes

int m_bufLen
 the size of the stdio buffer More...
 
CriticalCString m_str
 this stores the data that was read More...
 
UINT m_msg
 message to send when data has been read More...
 
DWORD m_parentID
 ID of thread to send m_msg to. More...
 
CWinThread * m_thread
 pointer to our thread More...
 
- Protected Attributes inherited from StdoutRedirect
FILE * file
 stdout (subclasses can set this to something else, e.g. stderr) More...
 

Detailed Description

Defines a thread class for capturing stdout.

Constructor & Destructor Documentation

StdoutThread::StdoutThread ( void  )

References m_bufLen, m_msg, and m_parentID.

24 {
25  m_bufLen = 0;
26  m_msg = 0;
27  m_parentID = 0;
28 }
int m_bufLen
the size of the stdio buffer
Definition: StdoutThread.h:40
DWORD m_parentID
ID of thread to send m_msg to.
Definition: StdoutThread.h:43
UINT m_msg
message to send when data has been read
Definition: StdoutThread.h:42
StdoutThread::~StdoutThread ( void  )
virtual
32 {
33 }
StdoutThread::StdoutThread ( void  )
virtual StdoutThread::~StdoutThread ( void  )
virtual

Member Function Documentation

void StdoutThread::Get ( CString &  dst,
bool  clear 
)
inline

References CriticalCString::Get(), and m_str.

Referenced by COperatorConsoleApp::GetStdoutMsg().

34 {m_str.Get(dst, clear);}
CriticalCString m_str
this stores the data that was read
Definition: StdoutThread.h:41
void Get(CString &str, bool clear=false)
copy m_string into str, then optionally clear m_string
Definition: CriticalCString.cpp:40

Here is the call graph for this function:

Here is the caller graph for this function:

void StdoutThread::Get ( CString &  dst,
bool  clear 
)
inline

References CriticalCString::Get(), and m_str.

34 {m_str.Get(dst, clear);}
CriticalCString m_str
this stores the data that was read
Definition: StdoutThread.h:41
void Get(CString &str, bool clear=false)
copy m_string into str, then optionally clear m_string
Definition: CriticalCString.cpp:40

Here is the call graph for this function:

bool StdoutThread::InitThread ( int  bufLen,
UINT  threadMsg,
DWORD  parentID 
)
bool StdoutThread::InitThread ( int  bufLen,
UINT  threadMsg,
DWORD  parentID 
)

References StdoutRedirect::Init(), m_bufLen, m_msg, m_parentID, m_thread, StdoutRedirect::Start(), and ThreadProc().

Referenced by COperatorConsoleApp::InitOutput().

49 {
50  SECURITY_ATTRIBUTES security;
51 
52  m_bufLen = bufLen;
53  m_msg = threadMsg;
54  m_parentID = parentID;
55 
56  Init(m_bufLen); // open the pipes
57  Start(); // start getting output
58 
59  //
60  // Create the thread. We set auto delete to false so that we can tell when the thread
61  // quits (otherwise Windows would delete the thread when threadProc returns, and its handle
62  // would be invalid).
63  //
64  // In order to *safely* set auto delete, we have to create the thread in suspended mode.
65  // This ensures that the thread won't quit before we set auto delete.
66  //
67  security.nLength = sizeof(security);
68  security.lpSecurityDescriptor = NULL;
69  security.bInheritHandle = TRUE;
70 
71  m_thread = ::AfxBeginThread(ThreadProc, this, 0, 0, CREATE_SUSPENDED, &security);
72 
73  if (m_thread != NULL)
74  {
75  m_thread->m_bAutoDelete = FALSE;
76  m_thread->ResumeThread();
77  }
78 
79  return m_thread != NULL;
80 }
int Init(int bufferSize)
Definition: StdoutRedirect.cpp:75
CWinThread * m_thread
pointer to our thread
Definition: StdoutThread.h:44
int m_bufLen
the size of the stdio buffer
Definition: StdoutThread.h:40
static UINT __cdecl ThreadProc(void *param)
Definition: StdoutThread.cpp:136
DWORD m_parentID
ID of thread to send m_msg to.
Definition: StdoutThread.h:43
int Start()
Definition: StdoutRedirect.cpp:89
UINT m_msg
message to send when data has been read
Definition: StdoutThread.h:42

Here is the call graph for this function:

Here is the caller graph for this function:

void StdoutThread::Quit ( )

References StdoutRedirect::Close(), m_thread, and StdoutRedirect::Stop().

Referenced by COperatorConsoleApp::Quit().

36 {
37  if (m_thread != NULL)
38  {
39  Stop();
40  Close(); // close the pipe-- this will cause ThreadProc to return (i.e. terminate)
41  ::WaitForSingleObject(m_thread->m_hThread, INFINITE); // wait for it to quit
42  delete m_thread; // delete the thread
43  m_thread = NULL;
44  }
45 }
CWinThread * m_thread
pointer to our thread
Definition: StdoutThread.h:44
int Stop()
Definition: StdoutRedirect.cpp:100
void Close()
Definition: StdoutRedirect.cpp:64

Here is the call graph for this function:

Here is the caller graph for this function:

void StdoutThread::Quit ( )
UINT __cdecl StdoutThread::ThreadProc ( void *  param)
static

References CriticalCString::Append(), BUF_LEN, FindChar(), StdoutRedirect::GetBuffer(), m_bufLen, m_msg, m_parentID, m_str, and CriticalCString::Set().

Referenced by InitThread().

137 {
138  char *buf[2];
139  StdoutThread *data = (StdoutThread *)param;
140  char *src, *dst, *ch;
141  int bufIndex; // tells which buffer to read data into (buf[0] or buf[1])
142  int len; // the number of characters in the buffer
143  int bytesRead; // the number of bytes that were just read from the pipe
144  int leftover; // the number of characters remaining in the buffer after the newline
145  int index; // the array index of the last newline ('\n') in the buffer
146 
147 
148  //
149  // Allocate 2 buffers to hold the data read from the pipe
150  //
151  buf[0] = new char[data->m_bufLen];
152  buf[1] = new char[data->m_bufLen];
153 
154 
155  if ((buf[0] == NULL) || (buf[1] == NULL))
156  {
157  data->m_str.Set("Unable to allocate buffers in StdoutThread\n\r");
158  ::PostThreadMessage(data->m_parentID, data->m_msg, (WPARAM)0, (LPARAM)0); // tell the parent thread the data is ready
159  }
160  else
161  {
162  memset(buf[0], 0, data->m_bufLen);
163  memset(buf[1], 0, data->m_bufLen);
164 
165  bufIndex = 0;
166  len = 0;
167 
168  do
169  {
170  //
171  // Read all available data (up BUF_LEN bytes) from the pipe. Note that GetBuffer() will block until
172  // data is available or the pipe is closed. We start reading new data into the end of the buffer.
173  //
174  ch = buf[bufIndex] + len;
175  bytesRead = data->GetBuffer(ch, BUF_LEN);
176 
177  if (bytesRead > 0) // 0 means that the pipe was closed
178  {
179  //
180  // Look for a newline character in the buffer, starting at the end of the buffer
181  //
182  len += bytesRead; // total number of bytes in buf
183  index = FindChar(buf[bufIndex], '\n', len); // find last newline (if any) in buf (-1 means no newline was found)
184 
185  //
186  // If we found a newline, copy the string into the shared data buffer. It is possible that
187  // the string may contain more than one newline (i.e. more that one line of text), but that's
188  // okay-- we just want to make sure that we copy complete lines into the destination buffer.
189  //
190  if (index >= 0)
191  {
192  //
193  // Copy buf[0] to buf[index] (inclusive) into m_str. If data->m_str was empty before the copy,
194  // post a message to tell the parent thread that data is ready. If data->m_str wasn't empty
195  // that means that the parent thread hasn't gotten around to processing the previous message yet,
196  // so we don't need to post another message.
197  //
198  // An alternative to this system would be to pass a pointer to the string in PostThreadMessage,
199  // but then we would need to have several messages allocated ahead of time.
200  //
201  if (data->m_str.Append(buf[bufIndex], index+1))
202  {
203  ::PostThreadMessage(data->m_parentID, data->m_msg, (WPARAM)0, (LPARAM)0);
204  }
205 
206  //
207  // Copy any leftover characters into the other buffer
208  //
209  leftover = (len - index) - 1;
210 
211  if (leftover)
212  {
213  src = buf[bufIndex] + (index+1);
214  dst = buf[bufIndex ^ 1];
215  memcpy(dst, src, leftover); // if I used memmove() instead, I would only need 1 buffer
216  memset(buf[bufIndex], 0, data->m_bufLen); // this makes debugging easier
217  bufIndex ^= 1; // switch to other buffer 0 -> 1, 1-> 0
218  }
219 
220  len = leftover;
221  }
222  }
223  }
224  while (bytesRead > 0); // 0 means that the pipe has been closed
225 
226  delete [] buf[0];
227  delete [] buf[1];
228  }
229 
230  return 0;
231 }
#define BUF_LEN
Definition: StdoutThread.cpp:133
int m_bufLen
the size of the stdio buffer
Definition: StdoutThread.h:40
Defines a thread class for capturing stdout.
Definition: StdoutThread.h:28
bool Append(CString &str)
Definition: CriticalCString.cpp:87
CriticalCString m_str
this stores the data that was read
Definition: StdoutThread.h:41
static int FindChar(const char *buf, char c, int len, int delta)
Definition: StdoutThread.cpp:83
int GetBuffer(char *buffer, int size)
Definition: StdoutRedirect.cpp:107
DWORD m_parentID
ID of thread to send m_msg to.
Definition: StdoutThread.h:43
void Set(CString &str)
Definition: CriticalCString.cpp:52
UINT m_msg
message to send when data has been read
Definition: StdoutThread.h:42

Here is the call graph for this function:

Here is the caller graph for this function:

static UINT __cdecl StdoutThread::ThreadProc ( void *  param)
static

Member Data Documentation

int StdoutThread::m_bufLen
protected

the size of the stdio buffer

Referenced by InitThread(), StdoutThread(), and ThreadProc().

UINT StdoutThread::m_msg
protected

message to send when data has been read

Referenced by InitThread(), StdoutThread(), and ThreadProc().

DWORD StdoutThread::m_parentID
protected

ID of thread to send m_msg to.

Referenced by InitThread(), StdoutThread(), and ThreadProc().

CriticalCString StdoutThread::m_str
protected

this stores the data that was read

Referenced by Get(), and ThreadProc().

CWinThread * StdoutThread::m_thread
protected

pointer to our thread

Referenced by InitThread(), and Quit().


The documentation for this class was generated from the following files: