CloseHandle HANGS on HANDLE created from CreatePipe
Solution
Add CloseHandle(hChildStd_OUT_Wr) after CreateProcess(...)
Problematic Code
THREAD1:
HANDLE hChildStd_OUT_Rd;
HANDLE hChildStd_OUT_Wr;
CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0);
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hChildStd_OUT_Wr;
siStartInfo.hStdOutput = hChildStd_OUT_Wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
siStartInfo.wShowWindow = true;
// Create the child process.
bSuccess = CreateProcess(NULL,
executable, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
currentDir, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if (piProcInfo.hProcess != NULL)
{
// Waits here until process terminates
WaitForSingleObject (piProcInfo.hProcess, INFINITE);
// Process is terminated
if (hChildStd_OUT_Rd != NULL)
{
CloseHandle(hChildStd_OUT_Rd); <= HANGS HERE!!!
}
CloseHandle(piProcInfo.hProces);
if (piProcInfo.hThread != NULL)
{
CloseHandle(piProcInfo.hThread);
}
}
THREAD2:
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
int threadId = (int)QThread::currentThreadId();
qDebug() << "ReadFromPipe from threadId:" << threadId;
if (fileStdout_ == NULL)
{
qDebug() << "fileStdout_ is NULL, aborting";
return;
}
for (;; )
{
bSuccess = ReadFile( hChildStd_OUT_Rd_, chBuf, BUFSIZE, &dwRead, NULL);
if( !bSuccess || dwRead == 0 )
{
qDebug() << "qDebug() Failure reading hChildStd_OUT_Rd_";
break;
}
fwrite(chBuf, dwRead, 1, fileStdout_);
fflush(fileStdout_);
if (!bSuccess ) break;
}
qDebug() << "qDebug() hChildStd_OUT_Rd_ TERMINATED taskId:" << haiProcess_->taskId_;
if (hParentStdOut != INVALID_HANDLE_VALUE)
SetStdHandle(STD_OUTPUT_HANDLE, hParentStdOut);
fclose(fileStdout_);
fileStdout_ = NULL;
qDebug() << "qDebug() [ReadFromPipe] TERMINATED taskId:" << haiProcess_->taskId_;
Corrected Code
// Close inheritable copies of the handles you do not want to be
// inherited.
if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");
Recent Comments