Add forgotten files 1.4.70b
[polyglot.git] / engine.cpp
index b5429d9..f86f0fb 100644 (file)
@@ -11,6 +11,7 @@
 #include <cstring>\r
 \r
 #include <sys/types.h>\r
+#include <sys/resource.h>\r
 #include <unistd.h>\r
 \r
 #include "engine.h"\r
@@ -21,7 +22,7 @@
 \r
 // constants\r
 \r
-static const int StringSize = 4096;\r
+static const unsigned int StringSize = 4096;\r
 \r
 // variables\r
 \r
@@ -123,10 +124,9 @@ void engine_open(engine_t * engine) {
 \r
       // set a low priority\r
 \r
-      if (option_get_bool("UseNice"))\r
-      {\r
+      if (option_get_bool("UseNice")) {\r
           my_log("POLYGLOT Adjust Engine Piority");\r
-          nice(+option_get_int("NiceValue"));\r
+          nice(option_get_int("NiceValue"));\r
       }\r
 \r
       // change the current directory\r
@@ -159,18 +159,57 @@ void engine_open(engine_t * engine) {
       engine->io->in_fd = from_engine[0];\r
       engine->io->out_fd = to_engine[1];\r
       engine->io->name = "Engine";\r
+      engine->pid=pid;\r
+      engine->state|=ENGINE_ACTIVE; // can we test if this really true?\r
 \r
       io_init(engine->io);\r
    }\r
 }\r
 \r
+// engine_active\r
+\r
+bool engine_active(engine_t *engine){\r
+    return (engine->state & ENGINE_ACTIVE)!=0;\r
+}\r
+\r
+// engine_eof\r
+\r
+bool engine_eof(engine_t *engine){\r
+    return (engine->state & ENGINE_EOF)!=0;\r
+}\r
+\r
+// engine_set_nice_value()\r
+\r
+void engine_set_nice_value(engine_t * engine, int value){\r
+    setpriority(PRIO_PROCESS,engine->pid,value);\r
+}\r
+\r
+\r
 // engine_close()\r
 \r
 void engine_close(engine_t * engine) {\r
 \r
    ASSERT(engine_is_ok(engine));\r
 \r
+   char string[StringSize];\r
    io_close(engine->io);\r
+       // TODO: timeout\r
+   while (!engine_eof(engine)) {\r
+       engine_get(engine,string,StringSize); \r
+   }\r
+\r
+}\r
+\r
+// engine_get_non_blocking()\r
+\r
+bool engine_get_non_blocking(engine_t * engine, char string[], int size){\r
+    if(io_line_ready(engine->io)){\r
+        engine_get(engine,string,StringSize);\r
+        return true;\r
+    }else{\r
+        string[0]='\0';\r
+        return false;\r
+    }\r
 }\r
 \r
 // engine_get()\r
@@ -186,8 +225,7 @@ void engine_get(engine_t * engine, char string[], int size) {
    }\r
 \r
    if (!io_get_line(engine->io,string,size)) { // EOF\r
-       my_log("POLYGLOT *** EOF from Engine ***\n");\r
-      exit(EXIT_SUCCESS);\r
+       engine->state|=ENGINE_EOF;\r
    }\r
 }\r
 \r
@@ -283,6 +321,23 @@ engine_t Engine[1];
 \r
 // functions\r
 \r
+void set_affinity(engine_t *engine, int affin){\r
+       if(affin==-1) return;\r
+\r
+    typedef void (WINAPI *SPAM)(HANDLE, int);\r
+    SPAM pSPAM;\r
+    pSPAM = (SPAM) GetProcAddress(\r
+        GetModuleHandle(TEXT("kernel32.dll")), \r
+        "SetProcessAffinityMask");\r
+    if(NULL != pSPAM){\r
+            // [HGM] avoid crash on Win95 by first checking if API call exists\r
+        my_log("POLYGLOT Setting process affinity to %d\n",affin);\r
+        pSPAM((engine->io).hProcess,affin);\r
+    }else{\r
+        my_log("POLYGLOT API call \"SetProcessAffinityMask\" not available\n");\r
+    }\r
+}\r
+\r
 DWORD GetWin32Priority(int nice)\r
 {\r
 /*\r
@@ -300,71 +355,86 @@ IDLE_PRIORITY_CLASS         0x00000040
        return 0x00000040;\r
 }\r
 \r
-\r
-\r
-void set_affinity(engine_t *engine, int affin){\r
-       if(affin==-1) return;\r
-    SetProcessAffinityMask((engine->pipeEngine).hProcess,affin);\r
+void engine_set_nice_value(engine_t *engine, int value){\r
+    SetPriorityClass((engine->io).hProcess,\r
+                     GetWin32Priority(value));\r
 }\r
 \r
-\r
-\r
 void engine_send_queue(engine_t * engine,const char *szFormat, ...) {\r
-  nQueuePtr += vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1));\r
+    nQueuePtr += vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1));\r
 }\r
 \r
 void engine_send(engine_t * engine, const char *szFormat, ...) {\r
     vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1));\r
-    (engine->pipeEngine).LineOutput(szQueueString);\r
+    (engine->io).LineOutput(szQueueString);\r
     my_log("Adapter->Engine: %s\n",szQueueString);\r
     nQueuePtr = 0;\r
 }\r
 \r
 void engine_close(engine_t * engine){\r
-    (engine->pipeEngine).Close();\r
+    char string[StringSize];\r
+    (engine->io).Close();\r
+        // TODO: Timeout\r
+    while (!engine_eof(engine)) { \r
+      engine_get(Engine,string,StringSize);\r
+    }\r
+    (engine->io).Kill();\r
 }\r
 \r
-\r
 void engine_open(engine_t * engine){\r
-   int affinity;\r
+    int affinity;\r
     char *my_dir;\r
+    engine->state=0;\r
     if( (my_dir = _getcwd( NULL, 0 )) == NULL )\r
         my_fatal("Can't build path: %s\n",strerror(errno));\r
     SetCurrentDirectory(option_get_string("EngineDir"));\r
-    (engine->pipeEngine).Open(option_get_string("EngineCommand"));\r
-        //play with affinity (bad idea) \r
-    affinity=option_get_int("Affinity");\r
-    if(affinity!=-1) set_affinity(engine,affinity); //AAA\r
-        //lets go back\r
-    SetCurrentDirectory(my_dir);\r
-        // set a low priority\r
-    if (option_get_bool("UseNice")){\r
-          my_log("POLYGLOT Adjust Engine Piority\n");\r
-          SetPriorityClass((engine->pipeEngine).hProcess,\r
-                           GetWin32Priority(option_get_int("NiceValue")));\r
+    (engine->io).Open(option_get_string("EngineCommand"));\r
+    if((engine->io).Active()){\r
+        engine->state|=ENGINE_ACTIVE;\r
+            //play with affinity (bad idea)\r
+        affinity=option_get_int("Affinity");\r
+        if(affinity!=-1) set_affinity(engine,affinity); //AAA\r
+            //lets go back\r
+        SetCurrentDirectory(my_dir);\r
+            // set a low priority\r
+        if (option_get_bool("UseNice")){\r
+            my_log("POLYGLOT Adjust Engine Piority\n");\r
+            engine_set_nice_value(engine, option_get_int("NiceValue"));\r
+        }\r
     }\r
     \r
 }\r
 \r
+bool engine_active(engine_t *engine){\r
+    return (engine->state & ENGINE_ACTIVE)!=0;\r
+}\r
+\r
+bool engine_eof(engine_t *engine){\r
+    return (engine->state & ENGINE_EOF)!=0;\r
+}\r
+\r
 bool engine_get_non_blocking(engine_t * engine, char *szLineStr, int size){\r
-       if ((engine->pipeEngine).LineInput(szLineStr)) {\r
+    if(engine_eof(engine)){ return false;}\r
+    if ((engine->io).GetBuffer(szLineStr)) {\r
         my_log("Engine->Adapter: %s\n",szLineStr);\r
         return true;\r
     } else {\r
         szLineStr[0]='\0';\r
+        if(engine->io.EOF_()){\r
+            engine->state|=ENGINE_EOF;\r
+           my_log("POLYGLOT *** EOF from Engine ***\n");\r
+        }\r
         return false;\r
     }\r
 }\r
 \r
 void engine_get(engine_t * engine, char *szLineStr, int size){\r
-    bool data_available;\r
-    while(true){\r
-        data_available=engine_get_non_blocking(engine,szLineStr,size);\r
-        if(!data_available){\r
-            Idle();\r
-        }else{\r
-            break;\r
-        }\r
+    (engine->io).LineInput(szLineStr);\r
+    if(engine->io.EOF_()){\r
+      engine->state|=ENGINE_EOF;\r
+      my_log("POLYGLOT *** EOF from Engine ***\n");\r
+    }else{\r
+      my_log("Engine->Adapter: %s\n",szLineStr);\r
     }\r
 }\r
 \r