Re: How to check if a thread waits for data at the read-end of a pipe?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Arkady Frenkel (arkadyf_at_hotmailxdotxcom)
Date: 11/25/04


Date: Thu, 25 Nov 2004 11:17:35 +0200

If thread in waiting mode ( any ) you can use GetThreadContext()
Arkady

"Leif Erik Larsen" <leifel@online.no> wrote in message
news:Z8ipd.9526$rh1.241970@news2.e.nsc.no...
> After many tens of hours of searching Google, scanning programming
> groups, etc, I am almost about to give up. The only thing I have found
> is that there are (or at least has been) others struggling to find the
> answer to the same question as me, which makes me think that this is in
> fact something that is impossible, or at least difficult-, to do on
> Win32. So let me make some noice here once more, hopefully being more
> specific this time....
>
> I am about to port a C++ application (Larsen Commander) from OS/2 to
> Win32 and in the Win32 version I need a way to check (or get notified)
> when a thread or a process is waiting for data to be available at the
> read-end of my pipe. OS/2 has the API DosSetNPipeSem() that lets me
> attach a semaphore to a named pipe and I can then use the other API
> DosQueryNPipeSemState() to check if there is someone waiting at the
> read-end of the pipe. I guess Win32 has a way to let me do the same, but
> I am not able to find out how to do this using the standard Win32 SDK
> documentation. Anyone that can help?
>
> My application acts as a GUI command line shell in this regard. It has a
> console monitor and a command line where the user can launch internal
> and extarnal commands in the same way as with CMD.EXE. Larsen Commander
> launches command line programs as child processes, and redirects the
> child's STDIN, STDOUT and STDERR streams in standard documented ways.
> Everything works just great, except when it comes to one thing: When the
> child process attempts to read data from its STDIN it enters a
> wait-state because its STDIN-stream is empty. What I want to do in my
> application then is to show the command line in a special color mode, so
> the user can type some text of which to write to the pipe that feeds the
> childs STDIN. However, I find no way to check if there is someone at the
> read-end of the pipe waiting for data.
>
> Luckily (for my application and its users on Windows) most command line
> programs will never attempt to read anything from its STDIN, but some
> programs do. One example is UNZIP.EXE, which needs to get confirmations
> from the user (STDIN) e.g. before overwriting a file on the file system.
> UNZIP.EXE does this by reading from its STDIN.
>
> To be clear: The only information I need in order for this to work is a
> way to check if there is someone waiting for data at the read-end of my
> pipe.
>
> I am currently using an anonymous pipe created with Win32::CreatePipe(),
> but if I need to, and if it is possible, I can of course rewrite this to
> use a named pipe created with Win32:CreateNamedPipe(), or anything else.
> The best would be a way that is possible to work on all flavours of
> Win32, but it is also acceptible for me to use a technique only
> available on Win2000/XP.
>
> Remember: My application is a GUI application. Thus, I cannot use any
> console-based technique for this, as far as I can see.
>
> What I have tried are (code fragments only):
>
> 1) Using Win32::WaitForSingleObject() on the pipe file handle(s).
> ------------------------------------------------------------------
>
> // This doesn't seem to work (res will never be WAIT_TIMEOUT):
>
> HANDLE childStdInWriteSide = ...;
> HANDLE childStdInReadSide = ...;
> DWORD res = Win32::WaitForSingleObject(childStdInWriteSide, 0);
> if (res == WAIT_TIMEOUT) // If child wait for data at read-end?
> return true; // We never reach here! :-(
> else
> return false;
>
> // This doesn't work either (gives error "invalid handle"):
>
> HANDLE childStdInWriteSide = ...;
> HANDLE childStdInReadSide = ...;
> DWORD res = Win32::WaitForSingleObject(childStdInReadSide, 0);
> if (res == WAIT_TIMEOUT) // If child wait for data at read-end?
> return true; // We never reach here! :-(
> else
> return false;
>
> 2) Using Win32::NtQuerySystemInformation() to check the
> state of the child process thread(s).
> --------------------------------------------------------
>
> // This doesn't work (child process thread wait state
> // seems to be unstable).
>
> LPVOID infoBuff = ...;
> NtQuerySystemInformation(NT_PROCESSTHREAD_INFO, infoBuff, ...);
> PSYSTEM_PROCESSES p = (PSYSTEM_PROCESSES) infoBuff;
> for (;;)
> {
> if (p->ProcessId == myChildProcessInfo.dwProcessId)
> {
> // We have found the information for the child process of ours.
> int threadCount = p->ThreadCount;
> for (int i=0; i<threadCount; i++)
> {
> SYSTEM_THREADS* t = &p->Threads[i];
> if (t->State == StateWait &&
> (t->WaitReason == Executive ||
> t->WaitReason == WrLpcReply))
> {
> // This happens also when the thread is not actually
> // waiting on its STDIN, so I can't trust this.
> return true;
> }
> }
>
> // No need to test the remaining processes.
> break;
> }
> if (p->NextEntryDelta <= 0)
> break;
> p = (PSYSTEM_PROCESSES)((char*) p + p->NextEntryDelta);
> }
> return false;
>
> Thank you for reading all down to here. If you know I way to help me out
> of this problem I will be very, very happy.
>
> What about having a registration code of Larsen Commander for free? - To
> the person that first provides a solution that actually works!
>
> --
> Leif Erik Larsen
>
> Author of Larsen Commander
> Download for Windows and OS/2 available at
> http://home.online.no/~leifel/lcmd/index.html



Relevant Pages

  • How to check if a thread waits for data at the read-end of a pipe?
    ... Win32 and in the Win32 version I need a way to check ... attach a semaphore to a named pipe and I can then use the other API ... My application acts as a GUI command line shell in this regard. ... child's STDIN, STDOUT and STDERR streams in standard documented ways. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: How to redirect stdout to stdin?
    ... stdout of nc to its stdin. ... If you could connect the output of a command to its input, ... Use a pair of pipes, at least one of which must be a named pipe ...
    (comp.unix.shell)
  • Re: How to check if a thread waits for data at the read-end of a pipe?
    ... but I need to know the EXACT reason WHY the thread is in waiting ... >>My application acts as a GUI command line shell in this regard. ... >>child's STDIN, STDOUT and STDERR streams in standard documented ways. ... >>Author of Larsen Commander ...
    (microsoft.public.win32.programmer.kernel)
  • Re: A bit of grep and regex help?
    ... And here I was thinking redirection was implemented via close and open, the shell process having nothing to do as the stdin of the command was connected /for it by the shell/ directly to the file, ie the shell roughly did: ... connect write of pipe to stdout ...
    (alt.os.linux)
  • Re: piping into a python script
    ... Where I would be gathering strings from two places. ... otherwise I'd skip the pipe stuff totally. ... Usually Linux tools that can get the data from command line or files treat ... a single - as file name special with the meaning of: read from stdin. ...
    (comp.lang.python)