www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cancelling a stdin.read?

reply Lass Safin <lasssafin gmail.com> writes:
I have a multi-threaded program, one thread drawing to a window 
and handling it, the other handling stdin.

The thread which handles stdin is something like this:
char[] buf;
while(true) {
     readln(buf);
}

The window thread also has to receive close-events from the OS, 
such as when the user pressed Ctrl-Q or whatnot.
The following code is what I used to terminate my program:
import core.runtime : Runtime;
import core.stdc.stdlib : exit;
Runtime.terminate;
exit(0);

However this doesn't work, because Runtime.terminate waits for 
the other threads to terminate before proceeding.

So I thought about replacing my above loop with somethings like 
this:
while(NOTCLOSING) {
     ...
}

But this doesn't work either, because the conditional clause 
first gets read when a single loop finishes.
And my loop won't finish until I give it input via stdin.
This means that I can't use e.g. the close button for closing the 
button, without also writing to stdin.

Because of this, I have to resort to an exit(0) alone, forcing 
the program to terminate without running destructors (static 
destructors are my concern here..) of any kind.

Thus, my question is: Is there any way to cancel the read from 
stdin prematurely from another thread, so that the thread can 
finish?

Or perhaps, just running the shared static destructors alone, so 
that at least they can get run before closing via exit?
Apr 10 2016
next sibling parent reply hilop <hilop hilop.online.net> writes:
On Sunday, 10 April 2016 at 08:29:22 UTC, Lass Safin wrote:
 I have a multi-threaded program, one thread drawing to a window 
 and handling it, the other handling stdin.

 [...]
The external program that writes to the input has to close it when it has finished to write.
Apr 10 2016
parent Lass Safin <lasssafin gmail.com> writes:
On Sunday, 10 April 2016 at 18:00:31 UTC, hilop wrote:
 On Sunday, 10 April 2016 at 08:29:22 UTC, Lass Safin wrote:
 I have a multi-threaded program, one thread drawing to a 
 window and handling it, the other handling stdin.

 [...]
The external program that writes to the input has to close it when it has finished to write.
I'm writing from my terminal, and I have my graphical window opened beside it. I want to close the input from not an external program, but rather from within.
Apr 10 2016
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 10 April 2016 at 08:29:22 UTC, Lass Safin wrote:
 Thus, my question is: Is there any way to cancel the read from 
 stdin prematurely from another thread, so that the thread can 
 finish?
What operating system are you on? I wouldn't be using threads for this at all, you might want to reorganize the program to get terminal events sent to the same gui event loop so exiting it would exit all of it. But failing that, canceling an I/O request can be done by sending yourself a signal on posix and on Windows there's a system API call that one thread can cancel another thread's blocking read. The D library would see these cancels as an error and throw an exception. You could catch it or let it kill the thread, since you want to exit anyway.
Apr 11 2016
parent reply Lass Safin <lasssafin gmail.com> writes:
On Monday, 11 April 2016 at 14:53:31 UTC, Adam D. Ruppe wrote:
 On Sunday, 10 April 2016 at 08:29:22 UTC, Lass Safin wrote:
 Thus, my question is: Is there any way to cancel the read from 
 stdin prematurely from another thread, so that the thread can 
 finish?
What operating system are you on? I wouldn't be using threads for this at all, you might want to reorganize the program to get terminal events sent to the same gui event loop so exiting it would exit all of it. But failing that, canceling an I/O request can be done by sending yourself a signal on posix and on Windows there's a system API call that one thread can cancel another thread's blocking read. The D library would see these cancels as an error and throw an exception. You could catch it or let it kill the thread, since you want to exit anyway.
My savior! I can't put it in one loop, since the window also has some autonomous features.
Apr 11 2016
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 11 April 2016 at 14:57:27 UTC, Lass Safin wrote:
 I can't put it in one loop, since the window also has some 
 autonomous features.
Eh, my terminal.d and simpledisplay.d can combine event loops, you use a muliplexing function like select() on both the window and terminal so it waits for either or both at once without either blocking the other. It does mean you need to skip readln though, since its buffering can break those multiplexing functions. Well, anyway, take a gander at: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363794%28v=vs.85%29.aspx which is Windows Vista and up. or on linux send yourself a sigint https://en.wikipedia.org/wiki/SIGINT_%28POSIX%29 kill(getpid(), SIGINT); should do the trick. import core.sys.posix.signal; IIRC for those functions
Apr 11 2016