mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
cleanup and some fixes
This commit is contained in:
parent
a1c5c358f3
commit
d64c8a66dc
@ -17,6 +17,7 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// This define tells the windows headers to include job objects:
|
||||||
#define _WIN32_WINNT 0x0500
|
#define _WIN32_WINNT 0x0500
|
||||||
|
|
||||||
#include "directd.h"
|
#include "directd.h"
|
||||||
@ -38,11 +39,10 @@
|
|||||||
|
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
|
||||||
//#define old_directd
|
|
||||||
#undef old_directd
|
|
||||||
|
|
||||||
#ifdef old_directd //[
|
|
||||||
namespace {
|
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:
|
// The following is from an MSDN example:
|
||||||
|
|
||||||
#define TA_FAILED 0
|
#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() :
|
DirectD::DirectD() :
|
||||||
_reader(&_cm, 1), _writer(&_cm, 0), _listener(&_cm, 0),
|
_reader(&_cm, 1), _writer(&_cm, 0), _listener(&_cm, 0),
|
||||||
_shutdown(false) {
|
_jobObject(0), _shutdown(false), _useOldStuff(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectD::~DirectD() {
|
DirectD::~DirectD() {
|
||||||
@ -326,17 +215,49 @@ 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;
|
||||||
#ifdef old_directd //[
|
if (_useOldStuff) {
|
||||||
_pids.push_back(StartApp(cmd));
|
_pids.push_back(StartApp(cmd));
|
||||||
nout<<" pid="<<_pids.back()<<endl;
|
nout<<" pid="<<_pids.back()<<endl;
|
||||||
#else //][
|
} else {
|
||||||
StartApp(cmd);
|
if (!_jobObject) {
|
||||||
#endif //]
|
_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
|
void
|
||||||
DirectD::kill_app(int index) {
|
DirectD::kill_app(int index) {
|
||||||
#ifdef old_directd //[
|
if (_useOldStuff) {
|
||||||
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()) {
|
||||||
@ -344,27 +265,30 @@ DirectD::kill_app(int index) {
|
|||||||
TerminateApp((*pi), 1000);
|
TerminateApp((*pi), 1000);
|
||||||
_pids.erase(pi);
|
_pids.erase(pi);
|
||||||
}
|
}
|
||||||
#else //][
|
} else {
|
||||||
|
cerr<<"kill_app(index) not implemented, calling kill_all() instead."<<endl;
|
||||||
kill_all();
|
kill_all();
|
||||||
#endif //]
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DirectD::kill_all() {
|
DirectD::kill_all() {
|
||||||
#ifdef old_directd //[
|
if (_useOldStuff) {
|
||||||
PidStack::reverse_iterator pi;
|
PidStack::reverse_iterator pi;
|
||||||
for (pi = _pids.rbegin(); pi != _pids.rend(); ++pi) {
|
for (pi = _pids.rbegin(); pi != _pids.rend(); ++pi) {
|
||||||
nout<<"trying kill "<<(*pi)<<endl;
|
nout<<"trying kill "<<(*pi)<<endl;
|
||||||
TerminateApp((*pi), 1000);
|
TerminateApp((*pi), 1000);
|
||||||
}
|
}
|
||||||
_pids.clear();
|
_pids.clear();
|
||||||
#else //][
|
|
||||||
if (TerminateJobObject(sgJobObject, 0)) {
|
|
||||||
cerr<<"true TerminateJobObject"<<endl;
|
|
||||||
} else {
|
} else {
|
||||||
cerr<<"false TerminateJobObject"<<endl;
|
if (!_jobObject) {
|
||||||
|
cerr<<"kill_all(): No open _jobObject"<<endl;
|
||||||
|
} else if (!TerminateJobObject(_jobObject, 0)) {
|
||||||
|
cerr<<"kill_all() TerminateJobObject Error: "<<GetLastError()<<endl;
|
||||||
|
}
|
||||||
|
CloseHandle(_jobObject);
|
||||||
|
_jobObject=0;
|
||||||
}
|
}
|
||||||
#endif //]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#ifdef CPPPARSER //[
|
#ifdef CPPPARSER //[
|
||||||
// hack for interrogate
|
// hack for interrogate
|
||||||
typedef int intptr_t;
|
typedef int intptr_t;
|
||||||
|
typedef int HANDLE;
|
||||||
#endif //]
|
#endif //]
|
||||||
|
|
||||||
|
|
||||||
@ -144,11 +145,19 @@ protected:
|
|||||||
ConnectionWriter _writer;
|
ConnectionWriter _writer;
|
||||||
QueuedConnectionListener _listener;
|
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;
|
typedef pvector< long /*intptr_t*/ > PidStack;
|
||||||
PidStack _pids;
|
PidStack _pids;
|
||||||
|
// End of old stuff
|
||||||
|
|
||||||
typedef pset< PT(Connection) > ConnectionSet;
|
typedef pset< PT(Connection) > ConnectionSet;
|
||||||
ConnectionSet _connections;
|
ConnectionSet _connections;
|
||||||
|
HANDLE _jobObject;
|
||||||
bool _shutdown;
|
bool _shutdown;
|
||||||
|
|
||||||
void check_for_new_clients();
|
void check_for_new_clients();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user