foobar2000 SDK  2015-08-03
Public Member Functions | Data Fields | Protected Member Functions | Protected Attributes | Static Private Member Functions
ProcessUtils::SubProcess

#include <ProcessUtils.h>

+ Inheritance diagram for ProcessUtils::SubProcess:

Public Member Functions

 SubProcess (const char *exePath, DWORD timeOutMS=60 *1000)
 
 ~SubProcess ()
 
void Detach ()
 
bool IsRunning () const
 
 PFC_DECLARE_EXCEPTION (failure, std::exception,"Unexpected failure")
 
size_t read (void *p_buffer, size_t p_bytes, abort_callback &abort)
 
void Restart ()
 
void SetPriority (DWORD val)
 
void write (const void *p_buffer, size_t p_bytes, abort_callback &abort)
 

Data Fields

bool ProcessMessages
 
DWORD TimeOutMS
 

Protected Member Functions

void CleanUp (bool bDetach=false)
 

Protected Attributes

const pfc::string8 ExePath
 
HANDLE hEventRead
 
HANDLE hEventWrite
 
HANDLE hProcess
 
HANDLE hStdIn
 
HANDLE hStdOut
 

Static Private Member Functions

static void _Close (HANDLE &h)
 
static pfc::string_formatter makePipeName ()
 
static void myCreatePipe (HANDLE &in, HANDLE &out)
 
static void myCreatePipeIn (HANDLE &in, HANDLE &out)
 
static void myCreatePipeOut (HANDLE &in, HANDLE &out)
 

Detailed Description

Definition at line 133 of file ProcessUtils.h.

Constructor & Destructor Documentation

ProcessUtils::SubProcess::SubProcess ( const char *  exePath,
DWORD  timeOutMS = 60*1000 
)
inline

Definition at line 137 of file ProcessUtils.h.

137  : ExePath(exePath), hStdIn(), hStdOut(), hProcess(), ProcessMessages(false), TimeOutMS(timeOutMS) {
138  HANDLE ev;
139  WIN32_OP( (ev = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL );
140  hEventRead = ev;
141  WIN32_OP( (ev = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL );
142  hEventWrite = ev;
143  Restart();
144  }
typedef HANDLE(WINAPI *pPowerCreateRequest_t)(__in void *Context)
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName)
Definition: pp-winapi.h:8
const pfc::string8 ExePath
Definition: ProcessUtils.h:201
ProcessUtils::SubProcess::~SubProcess ( )
inline

Definition at line 172 of file ProcessUtils.h.

172  {
173  CleanUp();
174  CloseHandle(hEventRead);
175  CloseHandle(hEventWrite);
176  }
void CleanUp(bool bDetach=false)
Definition: ProcessUtils.h:203

Member Function Documentation

static void ProcessUtils::SubProcess::_Close ( HANDLE h)
inlinestaticprivate

Definition at line 217 of file ProcessUtils.h.

217  {
218  if (h != NULL) {CloseHandle(h); h = NULL;}
219  }
void ProcessUtils::SubProcess::CleanUp ( bool  bDetach = false)
inlineprotected

Definition at line 203 of file ProcessUtils.h.

203  {
205  if (hProcess != NULL) {
206  if (!bDetach) {
207  if (WaitForSingleObject(hProcess, TimeOutMS) != WAIT_OBJECT_0) {
208  //PFC_ASSERT( !"Should not get here - worker stuck" );
209  console::formatter() << pfc::string_filename_ext(ExePath) << " unresponsive - terminating";
210  TerminateProcess(hProcess, -1);
211  }
212  }
213  _Close(hProcess);
214  }
215  }
Usage: console::formatter() << "blah " << somenumber << " asdf" << somestring;.
Definition: console.h:17
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
Definition: pp-winapi.h:16
const pfc::string8 ExePath
Definition: ProcessUtils.h:201
static void _Close(HANDLE &h)
Definition: ProcessUtils.h:217
void ProcessUtils::SubProcess::Detach ( )
inline

Definition at line 181 of file ProcessUtils.h.

181  {
182  CleanUp(true);
183  }
void CleanUp(bool bDetach=false)
Definition: ProcessUtils.h:203
bool ProcessUtils::SubProcess::IsRunning ( ) const
inline

Definition at line 178 of file ProcessUtils.h.

178  {
179  return hProcess != NULL;
180  }
static pfc::string_formatter ProcessUtils::SubProcess::makePipeName ( )
inlinestaticprivate

Definition at line 226 of file ProcessUtils.h.

226  {
227  GUID id;
228  CoCreateGuid (&id);
229  return pfc::string_formatter() << "\\\\.\\pipe\\" << pfc::print_guid(id);
230  }
Definition: pfc.h:71
string8_fastalloc string_formatter
Definition: string_base.h:615
static void ProcessUtils::SubProcess::myCreatePipe ( HANDLE in,
HANDLE out 
)
inlinestaticprivate

Definition at line 221 of file ProcessUtils.h.

221  {
222  SECURITY_ATTRIBUTES Attributes = { sizeof(SECURITY_ATTRIBUTES), 0, true };
223  WIN32_OP( CreatePipe( &in, &out, &Attributes, 0 ) );
224  }
static void ProcessUtils::SubProcess::myCreatePipeIn ( HANDLE in,
HANDLE out 
)
inlinestaticprivate

Definition at line 251 of file ProcessUtils.h.

251  {
252  SECURITY_ATTRIBUTES Attributes = { sizeof(SECURITY_ATTRIBUTES), 0, true };
254  SetLastError(NO_ERROR);
255  HANDLE pipe = CreateNamedPipe(
256  pipeName,
257  FILE_FLAG_FIRST_PIPE_INSTANCE | PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
258  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
259  1,
260  1024*64,
261  1024*64,
262  NMPWAIT_USE_DEFAULT_WAIT,&Attributes);
263  if (pipe == INVALID_HANDLE_VALUE) throw exception_win32(GetLastError());
264 
265  out = CreateFile(pipeName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,&Attributes,OPEN_EXISTING,0,NULL);
266  DuplicateHandle ( GetCurrentProcess(), pipe, GetCurrentProcess(), &in, 0, FALSE, DUPLICATE_SAME_ACCESS );
267  CloseHandle(pipe);
268  }
typedef HANDLE(WINAPI *pPowerCreateRequest_t)(__in void *Context)
static pfc::string_formatter makePipeName()
Definition: ProcessUtils.h:226
static void ProcessUtils::SubProcess::myCreatePipeOut ( HANDLE in,
HANDLE out 
)
inlinestaticprivate

Definition at line 232 of file ProcessUtils.h.

232  {
233  SECURITY_ATTRIBUTES Attributes = { sizeof(SECURITY_ATTRIBUTES), 0, true };
235  SetLastError(NO_ERROR);
236  HANDLE pipe = CreateNamedPipe(
237  pipeName,
238  FILE_FLAG_FIRST_PIPE_INSTANCE | PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
239  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
240  1,
241  1024*64,
242  1024*64,
243  NMPWAIT_USE_DEFAULT_WAIT,&Attributes);
244  if (pipe == INVALID_HANDLE_VALUE) throw exception_win32(GetLastError());
245 
246  in = CreateFile(pipeName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,&Attributes,OPEN_EXISTING,0,NULL);
247  DuplicateHandle ( GetCurrentProcess(), pipe, GetCurrentProcess(), &out, 0, FALSE, DUPLICATE_SAME_ACCESS );
248  CloseHandle(pipe);
249  }
typedef HANDLE(WINAPI *pPowerCreateRequest_t)(__in void *Context)
static pfc::string_formatter makePipeName()
Definition: ProcessUtils.h:226
ProcessUtils::SubProcess::PFC_DECLARE_EXCEPTION ( failure  ,
std::exception  ,
"Unexpected failure"   
)
size_t ProcessUtils::SubProcess::read ( void *  p_buffer,
size_t  p_bytes,
abort_callback abort 
)
inline

Definition at line 192 of file ProcessUtils.h.

192  {
193  PipeIO reader(hStdOut, hEventRead, ProcessMessages, TimeOutMS);
194  return reader.read(p_buffer, p_bytes, abort);
195  }
void ProcessUtils::SubProcess::Restart ( )
inline

Definition at line 145 of file ProcessUtils.h.

145  {
146  CleanUp();
147  STARTUPINFO si = {};
148  try {
149  si.cb = sizeof(si);
150  si.dwFlags = STARTF_USESTDHANDLES | STARTF_FORCEOFFFEEDBACK;
151  //si.wShowWindow = SW_HIDE;
152 
153  myCreatePipeOut(si.hStdInput, hStdIn);
154  myCreatePipeIn(hStdOut, si.hStdOutput);
155  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
156 
157  PROCESS_INFORMATION pi = {};
158  try {
159  WIN32_OP( CreateProcess(pfc::stringcvt::string_os_from_utf8(ExePath), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) );
160  } catch(std::exception const & e) {
161  throw failure(pfc::string_formatter() << "Could not start the worker process - " << e);
162  }
163  hProcess = pi.hProcess; _Close(pi.hThread);
164  } catch(...) {
165  _Close(si.hStdInput);
166  _Close(si.hStdOutput);
167  CleanUp(); throw;
168  }
169  _Close(si.hStdInput);
170  _Close(si.hStdOutput);
171  }
void CleanUp(bool bDetach=false)
Definition: ProcessUtils.h:203
static void myCreatePipeIn(HANDLE &in, HANDLE &out)
Definition: ProcessUtils.h:251
const pfc::string8 ExePath
Definition: ProcessUtils.h:201
std::exception exception
Definition: primitives.h:193
static void _Close(HANDLE &h)
Definition: ProcessUtils.h:217
static void myCreatePipeOut(HANDLE &in, HANDLE &out)
Definition: ProcessUtils.h:232
void ProcessUtils::SubProcess::SetPriority ( DWORD  val)
inline

Definition at line 196 of file ProcessUtils.h.

196  {
197  SetPriorityClass(hProcess, val);
198  }
void ProcessUtils::SubProcess::write ( const void *  p_buffer,
size_t  p_bytes,
abort_callback abort 
)
inline

Definition at line 188 of file ProcessUtils.h.

188  {
189  PipeIO writer(hStdIn, hEventWrite, ProcessMessages, TimeOutMS);
190  writer.write(p_buffer, p_bytes, abort);
191  }

Field Documentation

const pfc::string8 ProcessUtils::SubProcess::ExePath
protected

Definition at line 201 of file ProcessUtils.h.

HANDLE ProcessUtils::SubProcess::hEventRead
protected

Definition at line 200 of file ProcessUtils.h.

HANDLE ProcessUtils::SubProcess::hEventWrite
protected

Definition at line 200 of file ProcessUtils.h.

HANDLE ProcessUtils::SubProcess::hProcess
protected

Definition at line 200 of file ProcessUtils.h.

HANDLE ProcessUtils::SubProcess::hStdIn
protected

Definition at line 200 of file ProcessUtils.h.

HANDLE ProcessUtils::SubProcess::hStdOut
protected

Definition at line 200 of file ProcessUtils.h.

bool ProcessUtils::SubProcess::ProcessMessages

Definition at line 184 of file ProcessUtils.h.

DWORD ProcessUtils::SubProcess::TimeOutMS

Definition at line 185 of file ProcessUtils.h.


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