Toggle stm in engine thread
authorH.G.Muller <hgm@hgm-xboard.(none)>
Fri, 21 Dec 2018 13:40:26 +0000 (14:40 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Fri, 21 Dec 2018 15:21:37 +0000 (16:21 +0100)
Changing the side to move out of sync (i.e. in the GUI thread) sometimes
led to starting of a spurious search, when a 'force' command preceding
the moves was still queued. We now have the dummy command that was there
to release the engine thread from waiting for the queue also toggle stm.
This required a slightly different logic for handling ponder hits in
the GUI thread. These can still safely toggle stm there, as the engine
won't stop pondering before it gets the ponder hit.
  To make sure incoming empty lines will not wreck this scheme, these
are now ignored.

UCI2WB.c

index 1140969..2ff532d 100644 (file)
--- a/UCI2WB.c
+++ b/UCI2WB.c
@@ -455,7 +455,7 @@ GUI2Engine()
        for(difficult=0; !difficult; ) { // read and handle commands that can (or must) be handled during thinking\r
        fflush(toE); fflush(stdout);\r
        if(!ReadLine(stdin, line)) printf("# EOF\n"), sprintf(line, "quit -1\n");\r
-       sscanf(line, "%s", command);\r
+       if(!sscanf(line, "%s", command)) return;\r
        if(!strcmp(command, "usermove")) { difficult--; break; } // for efficiency during game play, moves, time & otim are tried first\r
        else if(!strcmp(command, "time"))   sscanf(line+4, "%d", &myTime),  myTime  = (10*myTime)/unit;\r
        else if(!strcmp(command, "otim"))   sscanf(line+4, "%d", &hisTime), hisTime = (10*hisTime)/unit;\r
@@ -500,19 +500,18 @@ GUI2Engine()
        if(difficult < 0) { // used as kludge to signal "usermove" was already matched\r
            sscanf(line, "usermove %s", command); // strips off linefeed\r
            Move4Engine(command);\r
-           stm = WHITE+BLACK - stm; collect = (computer == ANALYZE); sm = 0;\r
+           collect = (computer == ANALYZE); sm = 0;\r
            // when pondering we either continue the ponder search as normal search, or abort it\r
-           if(searching) { // move cannot come during think, so we are pondering or analysing\r
-               if(searching == 1 && !strcmp(command, move[moveNr])) { // ponder hit\r
-                   char *draw = drawOffer ? " draw" : ""; drawOffer = 0;\r
-                   searching = 3; moveNr++; startTime = GetTickCount(); // clock starts running now\r
-                   EPRINT((f, "# ponderhit%s\n", draw)) fflush(toE); fflush(stdout);\r
-                   continue;\r
-               }\r
-               StopSearch(1);\r
+           if(searching == 1 && !strcmp(command, move[moveNr])) { // ponder hit\r
+               char *draw = drawOffer ? " draw" : ""; drawOffer = 0;\r
+               stm = WHITE+BLACK - stm;         // for acceptance of ponder move (can be safely done out of sync)\r
+               searching = 3; moveNr++; startTime = GetTickCount(); // clock starts running now\r
+               EPRINT((f, "# ponderhit%s\n", draw)) fflush(toE); fflush(stdout);\r
+           } else {\r
+               if(searching) StopSearch(1);     // ponder miss or analysis, as moves won't arrive during thinking\r
+               strcpy(move[moveNr++], command); // possibly overwrites ponder move\r
+               *qEnd++ = '\n'; Sync(WAKEUP);    // queue command to toggle stm\r
            }\r
-           strcpy(move[moveNr++], command); // possibly overwrites ponder move\r
-           *qEnd++ = '\n'; Sync(WAKEUP);    // make sure engine thread considers starting a search\r
        } else\r
        if(!strcmp(command, "resume")) {\r
            if(suspended == 2) StartPonder(moveNr); // restart interrupted ponder search\r
@@ -542,7 +541,7 @@ DoCommand ()
     int i;\r
 \r
     p=line; while(qStart < qEnd && (*p++ = *qStart++) != '\n') {} *p = 0;\r
-    if(line[0] == '\n') return;\r
+    if(line[0] == '\n') { stm = WHITE+BLACK - stm; return; }\r
     sscanf(line, "%s", command); DPRINT("# command %s\n", command), fflush(stdout);\r
 \r
        if(!strcmp(command, "new")) {\r