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

Started by
3 comments, last by SnT2k 18 years, 5 months ago
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?
Advertisement
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;    }}
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;	}}
Did you try to call FreeConsole () before exiting ?
--> The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones <--
*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]

This topic is closed to new replies.

Advertisement