瀏覽代碼

Merge pull request #741 from AtomicGameEngine/JME-ATOMIC-IPCUPDATES

IPC Updates for Windows child processes, WeakPtr fixes for WebClient
JoshEngebretson 9 年之前
父節點
當前提交
b9bc77bd6d

+ 29 - 0
Source/Atomic/IPC/IPC.cpp

@@ -33,6 +33,13 @@
 #include "IPC.h"
 #include "IPCEvents.h"
 
+#if defined(ATOMIC_PLATFORM_WINDOWS)
+
+#include <windows.h>
+#undef PostMessage
+
+#endif
+
 namespace Atomic
 {
 
@@ -40,6 +47,28 @@ IPC::IPC(Context* context) : Object(context),
     workerChannelID_(0)
 {
     SubscribeToEvent(E_BEGINFRAME, HANDLER(IPC, HandleBeginFrame));
+
+#ifdef ATOMIC_PLATFORM_WINDOWS
+
+    jobHandle_ = CreateJobObject(NULL, NULL);
+    if (!jobHandle_)
+    {
+        LOGERROR("IPC::IPC - Unable to create IPC job");
+    }
+    else
+    {
+        JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
+
+        // Configure all child processes associated with the job to terminate when main process is closed
+        jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+        if (0 == SetInformationJobObject(jobHandle_, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
+        {
+            LOGERROR("IPC::IPC - Unable set job information");
+            jobHandle_ = 0;
+        }
+    }
+
+#endif
 }
 
 IPC::~IPC()

+ 8 - 0
Source/Atomic/IPC/IPC.h

@@ -65,6 +65,10 @@ public:
     void SendEventToBroker(StringHash eventType);
     void SendEventToBroker(StringHash eventType, VariantMap& eventData);
 
+#ifdef ATOMIC_PLATFORM_WINDOWS
+    IPCHandle GetJobHandle() const { return jobHandle_; }
+#endif
+
 private:
 
     // if non-zero we're a worked and this is out broker's channel id
@@ -82,6 +86,10 @@ private:
     // valid on child
     SharedPtr<IPCWorker> worker_;
 
+#ifdef ATOMIC_PLATFORM_WINDOWS
+    IPCHandle jobHandle_;
+#endif
+
 };
 
 }

+ 14 - 0
Source/Atomic/IPC/IPCWindows.cpp

@@ -29,8 +29,11 @@
 #include <string>
 
 #include "../Core/Timer.h"
+#include "../IO/Log.h"
 #include "IPCWindows.h"
 
+#include "IPC.h"
+
 typedef std::wstring IPCWString;
 
 namespace Atomic
@@ -303,6 +306,17 @@ bool IPCProcess::Launch(const String& command, const Vector<String>& args, const
         return false;
     }
 
+    IPC* ipc = GetSubsystem<IPC>();
+    IPCHandle jobHandle = ipc->GetJobHandle();
+
+    if (jobHandle)
+    {
+        if (0 == AssignProcessToJobObject(jobHandle, pi.hProcess))
+        {
+            LOGERROR("IPCProcess::Launch - unable to assign job");
+        }
+    }
+
     pid_ = pi.hProcess;
     ::CloseHandle(pi.hThread);
 

+ 1 - 1
Source/Atomic/IPC/IPCWindows.h

@@ -132,7 +132,7 @@ private:
 
     IPCHandle pid_;
     IPCHandle clientRead_;
-    IPCHandle clientWrite_;
+    IPCHandle clientWrite_;    
 };
 
 }

+ 6 - 0
Source/Atomic/IPC/IPCWorker.cpp

@@ -101,10 +101,16 @@ void IPCWorker::ThreadFunction()
 {
     while (shouldRun_)
     {
+
+// On windows we use a job object to control process lifetime, we don't have a 
+// parent pid (these change and are reused on Windows, so we would need to DuplicateHandle and pass
+// to child on command line
+#ifndef ATOMIC_PLATFORM_WINDOWS
         if (!otherProcess_->IsRunning())
         {
             break;
         }
+#endif
 
         if (!Receive())
         {

+ 14 - 3
Source/AtomicWebView/WebClient.cpp

@@ -90,7 +90,7 @@ public:
     CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE
     {
 
-        if (webClient_->renderHandler_.Null())
+        if (webClient_.Null() || webClient_->renderHandler_.Null())
             return nullptr;
 
         return webClient_->renderHandler_->GetCEFRenderHandler();
@@ -487,6 +487,14 @@ public:
 
     IMPLEMENT_REFCOUNTING(WebClientPrivate);
 
+    void ClearReferences()
+    {
+        browser_ = nullptr;
+        webBrowserHost_ = nullptr;
+        webClient_ = nullptr;
+        browserSideRouter_ = nullptr;
+    }
+
 private:
 
     String initialLoadString_;
@@ -503,6 +511,7 @@ private:
 WebClient::WebClient(Context* context) : Object(context)
 {
     d_ = new WebClientPrivate(this);
+    d_->AddRef();
 
     SubscribeToEvent(E_WEBVIEWGLOBALPROPERTIESCHANGED, HANDLER(WebClient, HandleWebViewGlobalPropertiesChanged));
 }
@@ -520,10 +529,12 @@ WebClient::~WebClient()
         }
 
         d_->CloseBrowser(true);
+        d_->ClearReferences();
+        d_->Release();
     }
 
-    renderHandler_ = 0;
-    //d_->Release();
+    d_ = nullptr;
+    renderHandler_ = 0;    
 }
 
 void WebClient::SendMouseClickEvent(int x, int y, unsigned button, bool mouseUp, unsigned modifier, int clickCount) const