Dave Schuyler 23 лет назад
Родитель
Сommit
d64c8a66dc
2 измененных файлов с 64 добавлено и 131 удалено
  1. 54 130
      direct/src/directd/directd.cxx
  2. 10 1
      direct/src/directd/directd.h

+ 54 - 130
direct/src/directd/directd.cxx

@@ -17,6 +17,7 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+// This define tells the windows headers to include job objects:
 #define _WIN32_WINNT 0x0500
 
 #include "directd.h"
@@ -38,11 +39,10 @@
 
 #include "pset.h"
 
-//#define old_directd
-#undef old_directd
-
-#ifdef old_directd //[
 namespace {
+  // ...This section is part of the old stuff from the original implementation.
+  // The new stuff that uses job objects doesn't need this stuff:
+
   // The following is from an MSDN example:
   
   #define TA_FAILED 0
@@ -132,121 +132,10 @@ namespace {
   }
 
 }
-#else //][
-namespace {
-  // The following is from an MSDN example:
-  
-  #define TA_FAILED 0
-  #define TA_SUCCESS_CLEAN 1
-  #define TA_SUCCESS_KILL 2
-  #define TA_SUCCESS_16 3
-  
-  HANDLE sgJobObject;
-
-  BOOL CALLBACK
-  TerminateAppEnum(HWND hwnd, LPARAM lParam) {
-    DWORD dwID;
-    GetWindowThreadProcessId(hwnd, &dwID);
-    if(dwID == (DWORD)lParam) {
-       PostMessage(hwnd, WM_CLOSE, 0, 0);
-    }
-    return TRUE;
-  }
-
-  /*
-      DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout)
-
-      Purpose:
-        Shut down a 32-Bit Process
-
-      Parameters:
-        dwPID
-           Process ID of the process to shut down.
-
-        dwTimeout
-           Wait time in milliseconds before shutting down the process.
-
-      Return Value:
-        TA_FAILED - If the shutdown failed.
-        TA_SUCCESS_CLEAN - If the process was shutdown using WM_CLOSE.
-        TA_SUCCESS_KILL - if the process was shut down with
-           TerminateProcess().
-  */ 
-  DWORD WINAPI
-  TerminateApp(DWORD dwPID, DWORD dwTimeout) {
-    HANDLE   hProc;
-    DWORD   dwRet;
-
-    // If we can't open the process with PROCESS_TERMINATE rights,
-    // then we give up immediately.
-    hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID);
-    if(hProc == NULL) {
-       return TA_FAILED;
-    }
-
-    // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
-    // matches your process's.
-    EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM)dwPID);
-
-    // Wait on the handle. If it signals, great. If it times out,
-    // then you kill it.
-    if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0) {
-       dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
-    } else {
-       dwRet = TA_SUCCESS_CLEAN;
-    }
-    CloseHandle(hProc);
-
-    return dwRet;
-  }
-
-  /*
-      Start an application with the command line cmd.
-  */
-  void
-  StartApp(const string& cmd) {
-    static inited;
-    if (!inited) {
-      inited=1;
-      sgJobObject=CreateJobObject(0, 0);
-      if (!sgJobObject) {
-        nout<<"CreateProcess failed: no sgJobObject"<<endl;
-      }
-    }
-    DWORD pid=0;
-    STARTUPINFO si; 
-    PROCESS_INFORMATION pi; 
-    ZeroMemory(&si, sizeof(STARTUPINFO));
-    si.cb = sizeof(STARTUPINFO); 
-    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
-    if (CreateProcess(NULL, (char*)cmd.c_str(), 
-        0, 0, 1, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, 
-        0, 0, &si, &pi)) {
-      // The process must be created with CREATE_SUSPENDED to
-      // give us a chance to get the handle into our sgJobObject
-      // before the child processes starts sub-processes.
-      if (!AssignProcessToJobObject(sgJobObject, pi.hProcess)) {
-        // ...The assign failed.
-        CloseHandle(pi.hProcess);
-      }
-      else { CloseHandle(pi.hProcess); } //?????
-      // Because we called CreateProcess with the CREATE_SUSPEND flag,
-      // we must explicitly resume the processes main thread.
-      if (ResumeThread(pi.hThread) == -1) {
-        cerr<<"StartApp ResumeThread Error: "<<GetLastError()<<endl;
-      }
-      CloseHandle(pi.hThread);
-    } else {
-      nout<<"CreateProcess failed: "<<cmd<<endl;
-    }
-  }
-
-}
-#endif //]
 
 DirectD::DirectD() :
     _reader(&_cm, 1), _writer(&_cm, 0), _listener(&_cm, 0),
-    _shutdown(false) {
+    _jobObject(0), _shutdown(false), _useOldStuff(false) {
 }
 
 DirectD::~DirectD() {
@@ -326,17 +215,49 @@ DirectD::server_ready(const string& client_host, int port) {
 void
 DirectD::start_app(const string& cmd) {
   nout<<"start_app(cmd="<<cmd<<")"<<endl;
-  #ifdef old_directd //[
+  if (_useOldStuff) {
     _pids.push_back(StartApp(cmd));
     nout<<"    pid="<<_pids.back()<<endl;
-  #else //][
-    StartApp(cmd);
-  #endif //]
+  } else {
+    if (!_jobObject) {
+      _jobObject=CreateJobObject(0, 0);
+      if (!_jobObject) {
+        nout<<"CreateProcess failed: no _jobObject: "<<GetLastError()<<endl;
+        return;
+      }
+    }
+    DWORD pid=0;
+    STARTUPINFO si; 
+    PROCESS_INFORMATION pi; 
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    si.cb = sizeof(STARTUPINFO); 
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+    if (CreateProcess(NULL, (char*)cmd.c_str(), 
+        0, 0, 1, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, 
+        0, 0, &si, &pi)) {
+      // The process must be created with CREATE_SUSPENDED to
+      // give us a chance to get the handle into our sgJobObject
+      // before the child processes starts sub-processes.
+      if (!AssignProcessToJobObject(_jobObject, pi.hProcess)) {
+        // ...The assign failed.
+        cerr<<"StartJob AssignProcessToJobObject Error: "<<GetLastError()<<endl;
+      }
+      CloseHandle(pi.hProcess); //?????
+      // Because we called CreateProcess with the CREATE_SUSPEND flag,
+      // we must explicitly resume the processes main thread.
+      if (ResumeThread(pi.hThread) == -1) {
+        cerr<<"StartJob ResumeThread Error: "<<GetLastError()<<endl;
+      }
+      CloseHandle(pi.hThread);
+    } else {
+      nout<<"StartJob CreateProcess failed: "<<cmd<<endl;
+    }
+  }
 }
 
 void
 DirectD::kill_app(int index) {
-  #ifdef old_directd //[
+  if (_useOldStuff) {
     int i = _pids.size() - 1 - index % _pids.size();
     PidStack::iterator pi = _pids.begin() + i;
     if (pi!=_pids.end()) {
@@ -344,27 +265,30 @@ DirectD::kill_app(int index) {
       TerminateApp((*pi), 1000);
       _pids.erase(pi);
     }
-  #else //][
+  } else {
+    cerr<<"kill_app(index) not implemented, calling kill_all() instead."<<endl;
     kill_all();
-  #endif //]
+  }
 }
 
 void
 DirectD::kill_all() {
-  #ifdef old_directd //[
+  if (_useOldStuff) {
     PidStack::reverse_iterator pi;
     for (pi = _pids.rbegin(); pi != _pids.rend(); ++pi) {
       nout<<"trying kill "<<(*pi)<<endl;
       TerminateApp((*pi), 1000);
     }
     _pids.clear();
-  #else //][
-    if (TerminateJobObject(sgJobObject, 0)) {
-      cerr<<"true TerminateJobObject"<<endl;
-    } else {
-      cerr<<"false TerminateJobObject"<<endl;
+  } else {
+    if (!_jobObject) {
+      cerr<<"kill_all(): No open _jobObject"<<endl;
+    } else if (!TerminateJobObject(_jobObject, 0)) {
+      cerr<<"kill_all() TerminateJobObject Error: "<<GetLastError()<<endl;
     }
-  #endif //]
+    CloseHandle(_jobObject);
+    _jobObject=0;
+  }
 }
 
 void

+ 10 - 1
direct/src/directd/directd.h

@@ -28,6 +28,7 @@
 #ifdef CPPPARSER //[
 // hack for interrogate
 typedef int intptr_t;
+typedef int HANDLE;
 #endif //]
 
 
@@ -144,11 +145,19 @@ protected:
   ConnectionWriter _writer;
   QueuedConnectionListener _listener;
 
+  // Start of old stuff:
+  // This is used to switch to the original method of 
+  // starting applications.  It can be used on old systems
+  // that don't support job objects.  Eventually this stuff
+  // should be removed.
+  bool _useOldStuff;
   typedef pvector< long /*intptr_t*/ > PidStack;
   PidStack _pids;
+  // End of old stuff
+
   typedef pset< PT(Connection) > ConnectionSet;
   ConnectionSet _connections;
-
+  HANDLE _jobObject;
   bool _shutdown;
   
   void check_for_new_clients();