mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-20 09:06:45 +08:00
Rewrite how commands from GUI are read
Instead of polling for input use a dedicated listener thread to read commands from the GUI independently from other threads. To do this properly we have to delegate to the listener all the reading from the GUI: while searching but also while waiting for a command, like in std::getline(). So we have two possible behaviours: in-sync mode, in which the thread mimics std::getline() and the caller blocks until something is read from GUI, and async mode where the listener continuously reads and processes GUI commands while other threads are searching. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
@@ -439,6 +439,10 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) {
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Start async mode to catch UCI commands sent to us while searching,
|
||||
// like "quit", "stop", etc.
|
||||
Threads.start_listener();
|
||||
|
||||
// We're ready to start thinking. Call the iterative deepening loop function
|
||||
Move ponderMove = MOVE_NONE;
|
||||
Move bestMove = id_loop(pos, searchMoves, &ponderMove);
|
||||
@@ -462,6 +466,9 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) {
|
||||
// This makes all the threads to go to sleep
|
||||
Threads.set_size(1);
|
||||
|
||||
// From now on any UCI command will be read in-sync with Threads.getline()
|
||||
Threads.stop_listener();
|
||||
|
||||
// If we are pondering or in infinite search, we shouldn't print the
|
||||
// best move before we are told to do so.
|
||||
if (!StopRequest && (Limits.ponder || Limits.infinite))
|
||||
@@ -1912,38 +1919,6 @@ split_point_start: // At split points actual search starts from here
|
||||
static int lastInfoTime;
|
||||
int t = current_search_time();
|
||||
|
||||
// Poll for input
|
||||
if (input_available())
|
||||
{
|
||||
// We are line oriented, don't read single chars
|
||||
string command;
|
||||
|
||||
if (!std::getline(std::cin, command) || command == "quit")
|
||||
{
|
||||
// Quit the program as soon as possible
|
||||
Limits.ponder = false;
|
||||
QuitRequest = StopRequest = true;
|
||||
return;
|
||||
}
|
||||
else if (command == "stop")
|
||||
{
|
||||
// Stop calculating as soon as possible, but still send the "bestmove"
|
||||
// and possibly the "ponder" token when finishing the search.
|
||||
Limits.ponder = false;
|
||||
StopRequest = true;
|
||||
}
|
||||
else if (command == "ponderhit")
|
||||
{
|
||||
// The opponent has played the expected move. GUI sends "ponderhit" if
|
||||
// we were told to ponder on the same move the opponent has played. We
|
||||
// should continue searching but switching from pondering to normal search.
|
||||
Limits.ponder = false;
|
||||
|
||||
if (StopOnPonderhit)
|
||||
StopRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Print search information
|
||||
if (t < 1000)
|
||||
lastInfoTime = 0;
|
||||
@@ -1988,14 +1963,14 @@ split_point_start: // At split points actual search starts from here
|
||||
|
||||
void wait_for_stop_or_ponderhit() {
|
||||
|
||||
string command;
|
||||
string cmd;
|
||||
|
||||
// Wait for a command from stdin
|
||||
while ( std::getline(std::cin, command)
|
||||
&& command != "ponderhit" && command != "stop" && command != "quit") {};
|
||||
while (cmd != "ponderhit" && cmd != "stop" && cmd != "quit")
|
||||
Threads.getline(cmd);
|
||||
|
||||
if (command != "ponderhit" && command != "stop")
|
||||
QuitRequest = true; // Must be "quit" or getline() returned false
|
||||
if (cmd == "quit")
|
||||
QuitRequest = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2248,3 +2223,34 @@ void Thread::idle_loop(SplitPoint* sp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ThreadsManager::do_uci_async_cmd() processes the commands from GUI received
|
||||
// by listener thread while the other threads are searching.
|
||||
|
||||
void ThreadsManager::do_uci_async_cmd(const std::string& cmd) {
|
||||
|
||||
if (cmd == "quit")
|
||||
{
|
||||
// Quit the program as soon as possible
|
||||
Limits.ponder = false;
|
||||
QuitRequest = StopRequest = true;
|
||||
}
|
||||
else if (cmd == "stop")
|
||||
{
|
||||
// Stop calculating as soon as possible, but still send the "bestmove"
|
||||
// and possibly the "ponder" token when finishing the search.
|
||||
Limits.ponder = false;
|
||||
StopRequest = true;
|
||||
}
|
||||
else if (cmd == "ponderhit")
|
||||
{
|
||||
// The opponent has played the expected move. GUI sends "ponderhit" if
|
||||
// we were told to ponder on the same move the opponent has played. We
|
||||
// should continue searching but switching from pondering to normal search.
|
||||
Limits.ponder = false;
|
||||
|
||||
if (StopOnPonderhit)
|
||||
StopRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user