Thread overview
Cancelling a stdin.read?
Apr 10, 2016
Lass Safin
Apr 10, 2016
hilop
Apr 10, 2016
Lass Safin
Apr 11, 2016
Adam D. Ruppe
Apr 11, 2016
Lass Safin
Apr 11, 2016
Adam D. Ruppe
April 10, 2016
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?
April 10, 2016
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.
April 10, 2016
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.
April 11, 2016
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.
April 11, 2016
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.
April 11, 2016
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