Sign in to follow this  
SnT2k

Unity How to interrupt/kill cin out of its waiting state?

Recommended Posts

I have a console that goes with my application/game in debug mode, in order to make it accept user input, I made a thread which does a "cin >>" in order to poll for user input... The problem is, when I terminate the thread polling for input using "TerminateThread( hConsoleInput, 0 )", the console won't disappear. Instead, it just sits there for a while and Visual studio complains that the code is deadlocked... I searched through the web but I haven't found any answer (the closest I've found is this: http://www.gamedev.net/community/forums/topic.asp?topic_id=160658) and I've been trying to figure out how to do this for three hours -_-... anyway, does anybody have a solution?

Share this post


Link to post
Share on other sites
A few options:

1) Don't kill the thread (simplify it so all it does it copy input elsewhere to be processed, for example).
2) Close stdin. Hopefully this'll unblock the read causing an error condition. Don't think this is reversable. Probably also implementation dependant.
3) Use Boost.Iostreams to implement an istream that can be told to throw when you want the thread to die, by layering over asyncronous i/o and polling a member variable (e.g.:

void do_io( my_throwing_istream & example ) {
try {
std::string line;
while ( getline( example , line ) ) {
//...
}
}
catch( thread_being_terminated ) {
/* OK, presume we're the topmost funciton and end handling here for this
* example.
*/
return;
}
}

Share this post


Link to post
Share on other sites
So far, I only got #3... I only got a vague idea on #1 and don't know how to do #2. Anyway, I'll check boost libraries. Meanwhile, here's the code snippet that I use:

#include <iostream>
#include <windows.h>
HANDLE hConsoleInput = 0;
DWORD WINAPI InputThread( LPVOID lpParam ) {
while ( !g_bQuit ) {
std::wstring temp;

//insert handlers here
std::wcin >> temp;
if ( temp == L"quit" ) {
g_bQuit = true;
CloseHandle( hConsoleInput );
hConsoleInput = 0;
return 0;
}
}
return 0;
}

bool ConsoleInputStart() {
if ( hConsoleInput )
return false;
hConsoleInput = CreateThread( 0, 0, InputThread, 0, 0, 0 );
if ( hConsoleInput )
return true;
else return false;
};
void ConsoleInputEnd() {
if ( hConsoleInput ) {
TerminateThread( hConsoleInput, 0 );
WaitForSingleObject( hConsoleInput, INFINITE );
CloseHandle( hConsoleInput );
hConsoleInput = 0;
}
}

Share this post


Link to post
Share on other sites
*doink*...THAT'S what I'm looking for... Thanks a lot.

{Edit} Wait a sec, the console is freed, but it seems that the code isn't released.. (as in.. MSVS doesn't break out of debug mode.. which means...)

{More Edit} Finally made it work, I made it write a return "\r" escape sequence to STDIN using WriteConsole() before calling FreeConsole(); and it releases the program properly :3... or so I think. (it looks hackish though)

it goes like this:
void ConsoleInputEnd() {
if ( hConsoleInput ) {
WriteConsole(GetStdHandle(STD_INPUT_HANDLE), L"\r", 1, NULL, NULL );
FreeConsole();
TerminateThread( hConsoleInput, 0 );
WaitForSingleObject( hConsoleInput, INFINITE );
CloseHandle( hConsoleInput );
hConsoleInput = 0;
}
}



[Edited by - SnT2k on November 7, 2005 9:39:20 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this