Reputation: 709
In a Windows program with two threads: thread1
and thread2
.
When thread1
is blocked in the call fread(buffer, 1, 10, stdin)
waiting for input, is it possible to do something from thread2
to force fread
to return?
So far I tried calling fclose(stdin)
from thread2
, but it doesn't seem to work. The program gets stuck at the fclose
call until some input is avaible in the stdin
stream.
What I'm trying to achieve is to terminate thread1
gracefully instead of just killing it with TerminateThread
, because there's some work that thread1
has to do at the end.
Another thing to consider is that stdin
is one end of a named pipe. I don't have control over the program at the other end of the pipe.
What I need is just to disconnect my program from its end of the pipe (stdin
in this case).
Upvotes: 2
Views: 428
Reputation: 256
If you can't use CancelSynchronousIo
you can close the underlying file handle with CloseHandle
, like this:
CloseHandle((HANDLE)_get_osfhandle(_fileno(stdin))) ;
That should cause fread
to return.
Upvotes: 2
Reputation: 215193
Calling fclose(stdin)
is a very bad idea; it causes undefined behavior if it happens before the fread
(which it's not ordered with respect to) or if the thread calling fread
does anything else with stdin
after fread
returns, and it does not unblock the fread
since fclose
cannot proceed until it obtains a lock on stdin
, which the in-progress fread
is excluding.
stdio
is just fundamentally unsuitable for what you want to do here. You could patch it up via forwarding through a second pipe, with yet another thread reading from stdin
and writing into your new pipe. Then you could abort an fread
on the read end of your pipe by closing the write end of it. The extra thread would still be stuck, but that doesn't really matter if you're going to be terminating anyway. Alternatively (and this is probably cleaner) you would use file descriptors (or Windows file handles) instead of stdio and poll
(or the Windows equivalent) to determine whether there's input to be read. You could combine these approaches to put the Windows-specific file handle logic in the extra thread (thus being able to terminate it cleanly) and continue to use portable stdio
in your program logic thread.
Upvotes: 5