Procházet zdrojové kódy

Changed to job objects

Dave Schuyler před 23 roky
rodič
revize
2f76502673
1 změnil soubory, kde provedl 139 přidání a 9 odebrání
  1. 139 9
      direct/src/directd/directd.cxx

+ 139 - 9
direct/src/directd/directd.cxx

@@ -17,6 +17,8 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
+#define _WIN32_WINNT 0x0500
+
 #include "directd.h"
 #include "directd.h"
 /*#include "pandaFramework.h"
 /*#include "pandaFramework.h"
 #include "queuedConnectionManager.h"*/
 #include "queuedConnectionManager.h"*/
@@ -36,8 +38,10 @@
 
 
 #include "pset.h"
 #include "pset.h"
 
 
+//#define old_directd
+#undef old_directd
 
 
-
+#ifdef old_directd //[
 namespace {
 namespace {
   // The following is from an MSDN example:
   // The following is from an MSDN example:
   
   
@@ -128,7 +132,117 @@ 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() :
 DirectD::DirectD() :
     _reader(&_cm, 1), _writer(&_cm, 0), _listener(&_cm, 0),
     _reader(&_cm, 1), _writer(&_cm, 0), _listener(&_cm, 0),
@@ -212,12 +326,17 @@ DirectD::server_ready(const string& client_host, int port) {
 void
 void
 DirectD::start_app(const string& cmd) {
 DirectD::start_app(const string& cmd) {
   nout<<"start_app(cmd="<<cmd<<")"<<endl;
   nout<<"start_app(cmd="<<cmd<<")"<<endl;
-  _pids.push_back(StartApp(cmd));
-  nout<<"    pid="<<_pids.back()<<endl;
+  #ifdef old_directd //[
+    _pids.push_back(StartApp(cmd));
+    nout<<"    pid="<<_pids.back()<<endl;
+  #else //][
+    StartApp(cmd);
+  #endif //]
 }
 }
 
 
 void
 void
 DirectD::kill_app(int index) {
 DirectD::kill_app(int index) {
+  #ifdef old_directd //[
     int i = _pids.size() - 1 - index % _pids.size();
     int i = _pids.size() - 1 - index % _pids.size();
     PidStack::iterator pi = _pids.begin() + i;
     PidStack::iterator pi = _pids.begin() + i;
     if (pi!=_pids.end()) {
     if (pi!=_pids.end()) {
@@ -225,16 +344,27 @@ DirectD::kill_app(int index) {
       TerminateApp((*pi), 1000);
       TerminateApp((*pi), 1000);
       _pids.erase(pi);
       _pids.erase(pi);
     }
     }
+  #else //][
+    kill_all();
+  #endif //]
 }
 }
 
 
 void
 void
 DirectD::kill_all() {
 DirectD::kill_all() {
-  PidStack::reverse_iterator pi;
-  for (pi = _pids.rbegin(); pi != _pids.rend(); ++pi) {
-    nout<<"trying kill "<<(*pi)<<endl;
-    TerminateApp((*pi), 1000);
-  }
-  _pids.clear();
+  #ifdef old_directd //[
+    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;
+    }
+  #endif //]
 }
 }
 
 
 void
 void