My call to ReadFile
is deadlocking, and I believe this to be the problem described here: http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx
Unfortunately, I am still unable to make my code work. I'm actually not trying to write anything to stdin, but I guess I must be in some way I don't realise. I've tried creating a second thread, but I can't figure out which bit of the operation is supposed to go in that thread.
I'll include my code below. I'm sorry there's so much of it, but I've tried to strip it down to the minimum, and I've only included my process creation code.
I've tried moving the orders of the various parts around, but I can't get it to work in any order. The code seems to work for small outputs, but not for large outputs, but I need large outputs.
class STDOUT_WORK_ITEM
{
public:
HANDLE g_hChildStd_OUT_Rd;
std::wstringstream& ss;
STDOUT_WORK_ITEM(HANDLE _g_hChildStd_OUT_Rd, std::wstringstream& _ss) : g_hChildStd_OUT_Rd (_g_hChildStd_OUT_Rd), ss(_ss) { };
};
unsigned int _stdcall InternalCreateProcessStdOutHelperThread (void* param)
{
DWORD dwRead;
char chBuf[4096] = { 0 };
BOOL bSuccess = FALSE;
for (;;)
{
bSuccess = ReadFile(reinterpret_cast<STDOUT_WORK_ITEM*>(param)->g_hChildStd_OUT_Rd, chBuf, 4096, &dwRead, NULL);
if(!bSuccess || dwRead == 0)
break;
std::string temp = chBuf;
reinterpret_cast<STDOUT_WORK_ITEM*>(param)->ss << std::wstring(temp.begin(), temp.end());
if (dwRead < 4096)
break;
ZeroMemory(chBuf, dwRead);
}
_endthreadex(ERROR_SUCCESS);
return ERROR_SUCCESS;
}
bool function(...)
{
bool _return = true;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
LPWSTR szCmdline = _wcsdup(ExpandEnvironmentVariables(path).c_str());
LPWSTR szParameters = _wcsdup(args.c_str());
SECURITY_ATTRIBUTES saAttr;
memset(&saAttr, 0, sizeof(saAttr));
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, NULL))
_return = false;
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, NULL))
_return = false;
if (!_return)
{
CloseHandle(g_hChildStd_OUT_Rd);
CloseHandle(g_hChildStd_OUT_Wr);
free(szParameters);
free(szCmdline);
return false;
}
siStartupInfo.hStdError = g_hChildStd_OUT_Wr;
siStartupInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartupInfo.dwFlags |= STARTF_USESTDHANDLES;
if(CreateProcess(szCmdline, szParameters, NULL, NULL, stdOUT != NULL ? TRUE : FALSE, CREATE_NO_WINDOW, NULL, NULL, &siStartupInfo, &piProcessInfo) == FALSE)
{
// Fail
}
WaitForSingleObject(piProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(piProcessInfo.hProcess, exit_code);
std::wstringstream ss;
HANDLE hStdOutWorkMutex = CreateMutex(NULL, FALSE, NULL);
HANDLE hStdOutThread = (HANDLE)_beginthreadex(NULL, NULL, InternalCreateProcessStdOutHelperThread, &STDOUT_WORK_ITEM(g_hChildStd_OUT_Rd, ss), NULL, NULL);
WaitForSingleObject(hStdOutThread, INFINITE);
// Collect output from ss.str();
CloseHandle(g_hChildStd_OUT_Rd);
CloseHandle(g_hChildStd_OUT_Wr);
CloseHandle(piProcessInfo.hProcess);
CloseHandle(piProcessInfo.hThread);
free(szParameters);
free(szCmdline);
return _return;
}
Unfortunately, ReadFile
still deadlocks. Thank you very much for any help you can offer.