Eliminate polling in Windows
[uci2wb.git] / UCI2WB.c
index e709384..0050146 100644 (file)
--- a/UCI2WB.c
+++ b/UCI2WB.c
 #include <fcntl.h>\r
 #include <string.h>\r
 \r
-#ifdef _MSC_VER \r
-#define SLEEP() Sleep(1) \r
-#else \r
-#define SLEEP() usleep(10) \r
-#endif \r
-\r
 // Set VARIANTS for in WinBoard variant feature. (With -s option this will always be reset to use "shogi".)\r
 #  define VARIANTS "normal,xiangqi"\r
 \r
@@ -41,6 +35,21 @@ int statDepth, statScore, statNodes, statTime, currNr, size; char currMove[20];
 FILE *toE, *fromE;\r
 int pid;\r
 \r
+#ifdef WIN32\r
+WinPipe(HANDLE *hRd, HANDLE *hWr)\r
+{\r
+  SECURITY_ATTRIBUTES saAttr;\r
+\r
+  /* Set the bInheritHandle flag so pipe handles are inherited. */\r
+  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);\r
+  saAttr.bInheritHandle = TRUE;\r
+  saAttr.lpSecurityDescriptor = NULL;\r
+\r
+  /* Create a pipe */\r
+  return CreatePipe(hRd, hWr, &saAttr, 0);\r
+}\r
+#endif\r
+\r
 #define INIT 0\r
 #define WAKEUP 1\r
 #define PAUSE 2\r
@@ -49,7 +58,12 @@ void
 Sync (int action)\r
 {\r
 #ifdef WIN32\r
-       if(action == PAUSE) while(pause) SLEEP(); // in Windows we still rely on polling. :-(\r
+       static HANDLE hWr, hRd; DWORD d; char c;\r
+       switch(action) {\r
+           case INIT:   WinPipe(&hRd, &hWr); break;\r
+           case WAKEUP: WriteFile(hWr, "\n", 1, &d, NULL); break;\r
+           case PAUSE:  ReadFile(hRd, &c, 1, &d, NULL);\r
+       }\r
 #else\r
        static int syncPipe[2]; char c;\r
        switch(action) {\r
@@ -292,7 +306,7 @@ printf("# start search\n");
            } else fprintf(toE, "setoption name %s\n", line+7), printf("# setoption name %s\n", line+7);\r
        }\r
        else if(!strcmp(command, "protover")) {\r
-           printf("feature variants=\"%s\" setboard=1 usermove=1 debug=1 reuse=0 done=0\n", sc=='s' ? "shogi,5x5+5_shogi" : VARIANTS);\r
+           printf("feature variants=\"%s\" setboard=1 usermove=1 debug=1 ping=1 reuse=0 done=0\n", sc=='s' ? "shogi,5x5+5_shogi" : VARIANTS);\r
            fprintf(toE, "u%ci\n", sc); // this prompts UCI engine for options\r
        }\r
        else if(!strcmp(command, "setboard")) {\r
@@ -327,6 +341,7 @@ printf("# start search\n");
        else if(!strcmp(command, "nopost")) post = 0;\r
        else if(!strcmp(command, "easy"))   ponder = 0;\r
        else if(!strcmp(command, "hard"))   ponder = 1;\r
+       else if(!strcmp(command, "ping"))   pause = 1, fprintf(toE, "isready\n"), fflush(toE), Sync(PAUSE), printf("pong %s", line+5);\r
        else if(!strcmp(command, "memory")) sscanf(line, "memory %d", &memory);\r
        else if(!strcmp(command, "cores"))  sscanf(line, "cores %d", &cores);\r
        else if(!strcmp(command, "sd"))     sscanf(line, "sd %d", &depth);\r
@@ -341,22 +356,16 @@ StartEngine(char *cmdLine, char *dir)
 #ifdef WIN32\r
   HANDLE hChildStdinRd, hChildStdinWr,\r
     hChildStdoutRd, hChildStdoutWr;\r
-  SECURITY_ATTRIBUTES saAttr;\r
   BOOL fSuccess;\r
   PROCESS_INFORMATION piProcInfo;\r
   STARTUPINFO siStartInfo;\r
   DWORD err;\r
 \r
-  /* Set the bInheritHandle flag so pipe handles are inherited. */\r
-  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);\r
-  saAttr.bInheritHandle = TRUE;\r
-  saAttr.lpSecurityDescriptor = NULL;\r
-\r
   /* Create a pipe for the child's STDOUT. */\r
-  if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) return GetLastError();\r
+  if (! WinPipe(&hChildStdoutRd, &hChildStdoutWr)) return GetLastError();\r
 \r
   /* Create a pipe for the child's STDIN. */\r
-  if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) return GetLastError();\r
+  if (! WinPipe(&hChildStdinRd, &hChildStdinWr)) return GetLastError();\r
 \r
   SetCurrentDirectory(dir); // go to engine directory\r
 \r