summaryrefslogtreecommitdiffstats
path: root/o3d/plugin
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-03 19:49:35 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-03 19:49:35 +0000
commit91240c947358b33cc19c0923a06d116ab36737dd (patch)
tree7897c99ad9b41d7735c7a42e0ea75fe6f76760b3 /o3d/plugin
parent2e25a9f4152a90a179ad37206bff79e1198379d7 (diff)
downloadchromium_src-91240c947358b33cc19c0923a06d116ab36737dd.zip
chromium_src-91240c947358b33cc19c0923a06d116ab36737dd.tar.gz
chromium_src-91240c947358b33cc19c0923a06d116ab36737dd.tar.bz2
Asynchronous tick now uses NPN_PluginAsyncCall.URL streaming callbacks are now also asynchronous.Implemented NPN_PluginAsyncCall for IE.Allowed WM_PAINT handler to be reentered because it no longer calls into the browser (except to schedule an asynchronous tick if none is pending).Fixed a bug where the EventManager would crash if an event callback called cleanUp on the client.Cleanup destroys all the packs. Doing this in NPP_Destroy seems to make Chrome timeout and fail to load the next page.Tar and GZ decoding happens on a new thread.
Review URL: http://codereview.chromium.org/155733 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22305 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/plugin')
-rw-r--r--o3d/plugin/build.scons9
-rw-r--r--o3d/plugin/cross/main_thread_task_poster.cc64
-rw-r--r--o3d/plugin/cross/main_thread_task_poster.h57
-rw-r--r--o3d/plugin/cross/o3d_glue.cc61
-rw-r--r--o3d/plugin/cross/o3d_glue.h3
-rw-r--r--o3d/plugin/idl/archive_request.idl11
-rw-r--r--o3d/plugin/idl/file_request.idl3
-rw-r--r--o3d/plugin/linux/main_linux.cc16
-rw-r--r--o3d/plugin/mac/main_mac.mm16
-rw-r--r--o3d/plugin/npapi_host_control/win/host_control.cc11
-rw-r--r--o3d/plugin/npapi_host_control/win/host_control.h5
-rw-r--r--o3d/plugin/npapi_host_control/win/np_browser_proxy.cc19
-rw-r--r--o3d/plugin/npapi_host_control/win/np_browser_proxy.h4
-rw-r--r--o3d/plugin/plugin.gyp2
-rw-r--r--o3d/plugin/win/main_win.cc28
15 files changed, 233 insertions, 76 deletions
diff --git a/o3d/plugin/build.scons b/o3d/plugin/build.scons
index 6449232..53d4dcf 100644
--- a/o3d/plugin/build.scons
+++ b/o3d/plugin/build.scons
@@ -130,6 +130,7 @@ if env.Bit('mac'):
LIBS = [
'o3dStatsreport_Common',
'o3dStatsreport',
+ 'event',
logging_lib,
],
FRAMEWORKS = [
@@ -150,7 +151,12 @@ if env.Bit('mac'):
)
if env.Bit('linux'):
- env.Append(CPPDEFINES = ['XP_UNIX', 'MOZ_X11']);
+ env.Append(
+ CPPDEFINES = ['XP_UNIX', 'MOZ_X11'],
+ LIBS = [
+ 'event',
+ ],
+ );
# Add libraries based on the requested renderer
env.Append(CPPPATH = env['RENDERER_INCLUDE_PATH'],
@@ -183,6 +189,7 @@ inputs = AUTOGEN_CC_FILES + [
'cross/async_loading.cc',
'cross/archive_request_static_glue.cc',
'cross/blacklist.cc',
+ 'cross/main_thread_task_poster.cc',
'cross/o3d_glue.cc',
'cross/np_v8_bridge.cc',
'cross/out_of_memory.cc',
diff --git a/o3d/plugin/cross/main_thread_task_poster.cc b/o3d/plugin/cross/main_thread_task_poster.cc
new file mode 100644
index 0000000..24a42e2
--- /dev/null
+++ b/o3d/plugin/cross/main_thread_task_poster.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <npapi.h>
+#include "plugin/cross/main_thread_task_poster.h"
+
+namespace o3d {
+
+MainThreadTaskPoster::MainThreadTaskPoster(ServiceLocator* service_locator,
+ NPP npp)
+ : service_(service_locator, this),
+ npp_(npp) {
+}
+
+MainThreadTaskPoster::~MainThreadTaskPoster() {
+}
+
+bool MainThreadTaskPoster::IsSupported() {
+ int plugin_major, plugin_minor, browser_major, browser_minor;
+ NPN_Version(&plugin_major, &plugin_minor, &browser_major, &browser_minor);
+ return browser_major > 0 ||
+ browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL;
+}
+
+void MainThreadTaskPoster::PostTask(Task* task) {
+ DCHECK(IsSupported());
+ NPN_PluginThreadAsyncCall(npp_, &MainThreadTaskPoster::RunTask, task);
+}
+
+void MainThreadTaskPoster::RunTask(void* data) {
+ Task* task = static_cast<Task*>(data);
+ task->Run();
+ delete task;
+}
+} // namespace o3d
diff --git a/o3d/plugin/cross/main_thread_task_poster.h b/o3d/plugin/cross/main_thread_task_poster.h
new file mode 100644
index 0000000..e322af1
--- /dev/null
+++ b/o3d/plugin/cross/main_thread_task_poster.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
+#define O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
+
+#include <npapi.h>
+#include "core/cross/imain_thread_task_poster.h"
+#include "core/cross/service_implementation.h"
+
+namespace o3d {
+
+class MainThreadTaskPoster : public IMainThreadTaskPoster {
+ public:
+ MainThreadTaskPoster(ServiceLocator* service_locator, NPP npp);
+ virtual ~MainThreadTaskPoster();
+ virtual bool IsSupported();
+ virtual void PostTask(Task* task);
+ private:
+ static void RunTask(void* data);
+ ServiceImplementation<IMainThreadTaskPoster> service_;
+ NPP npp_;
+ DISALLOW_COPY_AND_ASSIGN(MainThreadTaskPoster);
+};
+
+} // namespace o3d
+
+#endif // O3D_PLUGIN_CROSS_MAIN_THREAD_TASK_POSTER_H
diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc
index 9d6c24e..9053255 100644
--- a/o3d/plugin/cross/o3d_glue.cc
+++ b/o3d/plugin/cross/o3d_glue.cc
@@ -101,6 +101,7 @@ PluginObject::PluginObject(NPP npp)
client_info_manager_(&service_locator_),
object_manager_(&service_locator_),
profiler_(&service_locator_),
+ main_thread_task_poster_(&service_locator_, npp),
fullscreen_(false),
renderer_(NULL),
features_(NULL),
@@ -822,52 +823,52 @@ void PluginObject::PlatformSpecificSetCursor() {
#endif // OS_LINUX
-void PluginObject::AsyncTick() {
- if (pending_ticks_ >= 1)
+namespace {
+void TickPluginObject(void* data) {
+ PluginObject* plugin_object = static_cast<PluginObject*>(data);
+
+ // Check the plugin has not been destroyed already. Chrome sometimes invokes
+ // async callbacks after destruction.
+ if (!plugin_object->client())
return;
- class TickCallback : public StreamManager::FinishedCallback {
- public:
- explicit TickCallback(PluginObject* plugin_object)
- : plugin_object_(plugin_object) {
- }
+ // Don't allow reentrancy through asynchronous ticks. Chrome sometimes does
+ // this. It is also possible for the asyncronous call to be invoked while
+ // a message is being handled. This prevents that.
+ Client::ScopedIncrement reentrance_count(plugin_object->client());
+ if (reentrance_count.get() > 1)
+ return;
- virtual void Run(DownloadStream*,
- bool,
- const std::string&,
- const std::string&) {
- plugin_object_->Tick();
- }
+ plugin_object->Tick();
+}
+}
- private:
- PluginObject* plugin_object_;
- };
+void PluginObject::AsyncTick() {
+ if (pending_ticks_ >= 1)
+ return;
++pending_ticks_;
- // Invoke Client::Tick and Client::RenderClient in a way that is asynchronous
- // in Chrome. This avoids issues with making calls into the browser from a
- // message handler.
- // If NPN_PluginThreadAsyncCall worked in more browsers, it would be simpler
- // to use that.
- // We're calling LoadURL here with a URL that will return 0 bytes on browsers
- // that support the "data:" protocol and fail in browsers that don't like IE.
- // On browsers that support it, the side effect is to call the TickCallback.
- if (!stream_manager_->LoadURL("data:,", NULL, NULL, NULL,
- new TickCallback(this), NP_NORMAL)) {
- // Fallback on synchronous call if asynchronous load fails.
+ // Invoke Tick asynchronously if NPN_PluginThreadAsyncCall is supported.
+ // Otherwise invoke it synchronously.
+ int plugin_major, plugin_minor, browser_major, browser_minor;
+ NPN_Version(&plugin_major, &plugin_minor, &browser_major, &browser_minor);
+ if (browser_major > 0 ||
+ browser_minor >= NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
+ NPN_PluginThreadAsyncCall(npp_, TickPluginObject, this);
+ } else {
Tick();
}
}
void PluginObject::Tick() {
+ DCHECK(pending_ticks_ > 0);
+ --pending_ticks_;
+
client_->Tick();
if (renderer_ && renderer_->need_to_render()) {
client_->RenderClient(true);
}
-
- DCHECK(pending_ticks_ > 0);
- --pending_ticks_;
}
} // namespace _o3d
diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h
index c61d1d9..c318ea5 100644
--- a/o3d/plugin/cross/o3d_glue.h
+++ b/o3d/plugin/cross/o3d_glue.h
@@ -64,6 +64,7 @@
#include "core/cross/object_manager.h"
#include "core/cross/error.h"
#include "core/cross/profiler.h"
+#include "plugin/cross/main_thread_task_poster.h"
#include "plugin/cross/np_v8_bridge.h"
#include "client_glue.h"
#include "third_party/nixysa/static_glue/npapi/common.h"
@@ -85,6 +86,7 @@ using o3d::ClientInfoManager;
using o3d::EvaluationCounter;
using o3d::Features;
using o3d::EvaluationCounter;
+using o3d::MainThreadTaskPoster;
using o3d::ObjectManager;
using o3d::Profiler;
using o3d::Renderer;
@@ -129,6 +131,7 @@ class PluginObject: public NPObject {
ClientInfoManager client_info_manager_;
ObjectManager object_manager_;
Profiler profiler_;
+ MainThreadTaskPoster main_thread_task_poster_;
bool fullscreen_; // Are we rendered fullscreen or in the plugin region?
Renderer *renderer_;
Client *client_;
diff --git a/o3d/plugin/idl/archive_request.idl b/o3d/plugin/idl/archive_request.idl
index 1633a46..ef87f3e 100644
--- a/o3d/plugin/idl/archive_request.idl
+++ b/o3d/plugin/idl/archive_request.idl
@@ -31,8 +31,11 @@
namespace o3d {
+[include="import/cross/archive_request.h", async]
+callback void ArchiveReadyStateChangeCallback();
+
[include="import/cross/archive_request.h"]
-callback void ArchiveRequestCallback();
+callback void ArchiveFileAvailableCallback(RawData rawData);
%[
An ArchiveRequest object is used to carry out an asynchronous request for a
@@ -87,14 +90,14 @@ callback void ArchiveRequestCallback();
A callback that gets called each time readyState changes.
%]
[setter]
- ArchiveRequestCallback? onreadystatechange;
+ ArchiveReadyStateChangeCallback? onreadystatechange;
%[
A callback that gets called each time a file fully downloads and becomes
available.
%]
[setter]
- ArchiveRequestCallback? onfileavailable;
+ ArchiveFileAvailableCallback? onfileavailable;
%[
The uri of the archive being downloaded.
@@ -104,6 +107,8 @@ callback void ArchiveRequestCallback();
%[
A RawData object representing the file that is currently available.
Note: This value is only valid inside the onfileavailable callback.
+ Note: This property is deprecated. It is now an argument of the
+ onfileavailable callback.
%]
[getter] RawData? data;
diff --git a/o3d/plugin/idl/file_request.idl b/o3d/plugin/idl/file_request.idl
index 5b1c9a3..0e64812 100644
--- a/o3d/plugin/idl/file_request.idl
+++ b/o3d/plugin/idl/file_request.idl
@@ -31,7 +31,8 @@
namespace o3d {
-[include="core/cross/file_request.h"] callback void FileRequestCallback();
+[include="core/cross/file_request.h", async]
+callback void FileRequestCallback();
%[
A FileRequest object is used to carry out an asynchronous request for a file
diff --git a/o3d/plugin/linux/main_linux.cc b/o3d/plugin/linux/main_linux.cc
index b91c9d8..5fe7439 100644
--- a/o3d/plugin/linux/main_linux.cc
+++ b/o3d/plugin/linux/main_linux.cc
@@ -50,9 +50,12 @@ using o3d::Event;
namespace {
// We would normally make this a stack variable in main(), but in a
-// plugin, that's not possible, so we allocate it dynamically and
-// destroy it explicitly.
-scoped_ptr<base::AtExitManager> g_at_exit_manager;
+// plugin, that's not possible, so we make it a global. When the DLL is loaded
+// this it gets constructed and when it is unlooaded it is destructed. Note
+// that this cannot be done in NP_Initialize and NP_Shutdown because those
+// calls do not necessarily signify the DLL being loaded and unloaded. If the
+// DLL is not unloaded then the values of global variables are preserved.
+base::AtExitManager g_at_exit_manager;
bool g_xembed_support = false;
@@ -584,10 +587,6 @@ NPError InitializePlugin() {
if (!o3d::SetupOutOfMemoryHandler())
return NPERR_MODULE_LOAD_FAILED_ERROR;
- // Initialize the AtExitManager so that base singletons can be
- // destroyed properly.
- g_at_exit_manager.reset(new base::AtExitManager());
-
CommandLine::Init(0, NULL);
InitLogging("debug.log",
logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
@@ -636,9 +635,6 @@ NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) {
CommandLine::Terminate();
- // Force all base singletons to be destroyed.
- g_at_exit_manager.reset(NULL);
-
return NPERR_NO_ERROR;
}
diff --git a/o3d/plugin/mac/main_mac.mm b/o3d/plugin/mac/main_mac.mm
index 11355b7..ac47bb0 100644
--- a/o3d/plugin/mac/main_mac.mm
+++ b/o3d/plugin/mac/main_mac.mm
@@ -66,9 +66,12 @@ using o3d::Event;
namespace {
// We would normally make this a stack variable in main(), but in a
-// plugin, that's not possible, so we allocate it dynamically and
-// destroy it explicitly.
-scoped_ptr<base::AtExitManager> g_at_exit_manager;
+// plugin, that's not possible, so we make it a global. When the DLL is loaded
+// this it gets constructed and when it is unlooaded it is destructed. Note
+// that this cannot be done in NP_Initialize and NP_Shutdown because those
+// calls do not necessarily signify the DLL being loaded and unloaded. If the
+// DLL is not unloaded then the values of global variables are preserved.
+base::AtExitManager g_at_exit_manager;
#define CFTIMER
// #define DEFERRED_DRAW_ON_NULLEVENTS
@@ -500,10 +503,6 @@ NPError InitializePlugin() {
o3d::gRenderTimer.Start();
#endif // CFTIMER
- // Initialize the AtExitManager so that base singletons can be
- // destroyed properly.
- g_at_exit_manager.reset(new base::AtExitManager());
-
// Turn on the logging.
CommandLine::Init(0, NULL);
InitLogging("debug.log",
@@ -691,9 +690,6 @@ NPError OSCALL NP_Shutdown(void) {
o3d::gRenderTimer.Stop();
#endif
- // Force all base singletons to be destroyed.
- g_at_exit_manager.reset(NULL);
-
o3d::ShutdownBreakpad();
#endif // O3D_INTERNAL_PLUGIN
diff --git a/o3d/plugin/npapi_host_control/win/host_control.cc b/o3d/plugin/npapi_host_control/win/host_control.cc
index 117245c..957f465 100644
--- a/o3d/plugin/npapi_host_control/win/host_control.cc
+++ b/o3d/plugin/npapi_host_control/win/host_control.cc
@@ -260,6 +260,17 @@ LRESULT CHostControl::OnDestroy(UINT uMsg,
return 0;
}
+LRESULT CHostControl::OnPluginAsyncCall(UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ BOOL& handled) {
+ typedef void (*Function)(void*);
+ Function function = reinterpret_cast<Function>(w_param);
+ void* data = reinterpret_cast<void*>(l_param);
+ function(data);
+ handled = TRUE;
+ return 0;
+}
HRESULT CHostControl::FinalConstruct() {
return ConstructPluginProxy();
diff --git a/o3d/plugin/npapi_host_control/win/host_control.h b/o3d/plugin/npapi_host_control/win/host_control.h
index 5cf50ad..ae37487 100644
--- a/o3d/plugin/npapi_host_control/win/host_control.h
+++ b/o3d/plugin/npapi_host_control/win/host_control.h
@@ -58,6 +58,8 @@
class NPPluginProxy;
+const UINT WM_PLUGINASYNCCALL = WM_USER + 100;
+
// Class implementing an ActiveX control for containing NPAPI plugin-objects.
// This needs to be CComMultiThreadModel because these objects are concurrently
// AddRefed and Released from StreamOperation threads.
@@ -110,6 +112,7 @@ DECLARE_REGISTRY_RESOURCEID(IDR_HOSTCONTROL)
BEGIN_MSG_MAP(CHostControl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
+ MESSAGE_HANDLER(WM_PLUGINASYNCCALL, OnPluginAsyncCall)
END_MSG_MAP()
BEGIN_CONNECTION_POINT_MAP(CHostControl)
@@ -176,6 +179,8 @@ END_PROP_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnPluginAsyncCall(UINT message, WPARAM w_param, LPARAM l_param,
+ BOOL& handled);
// Initiates a data transfer, calling back into the hosted plug-in instance
// on status updates. Does not block on the transfer.
diff --git a/o3d/plugin/npapi_host_control/win/np_browser_proxy.cc b/o3d/plugin/npapi_host_control/win/np_browser_proxy.cc
index 968e71e..bba80d1 100644
--- a/o3d/plugin/npapi_host_control/win/np_browser_proxy.cc
+++ b/o3d/plugin/npapi_host_control/win/np_browser_proxy.cc
@@ -63,7 +63,7 @@ NPError OpenURL(NPBrowserProxy* browser_proxy,
NPNetscapeFuncs NPBrowserProxy::kNetscapeFunctions = {
sizeof(kNetscapeFunctions),
- NPVERS_HAS_NPOBJECT_ENUM,
+ NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL,
NPN_GetURL,
NPN_PostURL,
NPN_RequestRead,
@@ -107,6 +107,7 @@ NPNetscapeFuncs NPBrowserProxy::kNetscapeFunctions = {
NULL,
NULL,
NPN_Enumerate,
+ NPN_PluginThreadAsyncCall,
};
NPBrowserProxy::NPBrowserProxy(CHostControl* host, IDispatchEx* window_dispatch)
@@ -790,6 +791,22 @@ bool NPBrowserProxy::NPN_Evaluate(NPP npp,
return success;
}
+void NPBrowserProxy::NPN_PluginThreadAsyncCall(NPP npp,
+ void (*function)(void *),
+ void *data) {
+ if (!npp || !function) {
+ return;
+ }
+
+ NPBrowserProxy *browser_proxy = static_cast<NPBrowserProxy*>(npp->ndata);
+ CHostControl *host_control = browser_proxy->GetHostingControl();
+ ATLASSERT(host_control);
+
+ host_control->PostMessage(WM_PLUGINASYNCCALL,
+ reinterpret_cast<WPARAM>(function),
+ reinterpret_cast<LPARAM>(data));
+}
+
void NPBrowserProxy::NPN_SetException(NPObject *obj,
const NPUTF8 *message) {
ATLASSERT(false && "NPN_SetException not implemented");
diff --git a/o3d/plugin/npapi_host_control/win/np_browser_proxy.h b/o3d/plugin/npapi_host_control/win/np_browser_proxy.h
index e245c84..4c28cea 100644
--- a/o3d/plugin/npapi_host_control/win/np_browser_proxy.h
+++ b/o3d/plugin/npapi_host_control/win/np_browser_proxy.h
@@ -266,6 +266,10 @@ class NPBrowserProxy {
NPString *script,
NPVariant *result);
+ static void NPN_PluginThreadAsyncCall(NPP npp,
+ void (*function)(void *),
+ void *data);
+
static void NPN_SetException(NPObject *obj, const NPUTF8 *message);
// Static table of function pointers to the member function entry points
diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp
index 22a881e..f241187 100644
--- a/o3d/plugin/plugin.gyp
+++ b/o3d/plugin/plugin.gyp
@@ -50,6 +50,8 @@
'cross/download_stream.h',
'cross/main.cc',
'cross/main.h',
+ 'cross/main_thread_task_poster.cc',
+ 'cross/main_thread_task_poster.h',
'cross/marshaling_utils.h',
'cross/np_v8_bridge.cc',
'cross/np_v8_bridge.h',
diff --git a/o3d/plugin/win/main_win.cc b/o3d/plugin/win/main_win.cc
index 69cd647..f2feeae 100644
--- a/o3d/plugin/win/main_win.cc
+++ b/o3d/plugin/win/main_win.cc
@@ -90,9 +90,12 @@ namespace {
const wchar_t* const kFullScreenWindowClassName = L"O3DFullScreenWindowClass";
// We would normally make this a stack variable in main(), but in a
-// plugin, that's not possible, so we allocate it dynamically and
-// destroy it explicitly.
-scoped_ptr<base::AtExitManager> g_at_exit_manager;
+// plugin, that's not possible, so we make it a global. When the DLL is loaded
+// this it gets constructed and when it is unlooaded it is destructed. Note
+// that this cannot be done in NP_Initialize and NP_Shutdown because those
+// calls do not necessarily signify the DLL being loaded and unloaded. If the
+// DLL is not unloaded then the values of global variables are preserved.
+base::AtExitManager g_at_exit_manager;
static int HandleKeyboardEvent(PluginObject *obj,
HWND hWnd,
@@ -494,13 +497,6 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_PAINT: {
- if (reentrance_count.get() > 1) {
- // In Chrome, alert dialogs raised from JavaScript cause
- // reentrant WM_PAINT messages to be dispatched and 100% CPU
- // to be consumed unless we call this
- ::ValidateRect(hWnd, NULL);
- break; // Ignore this message; we're reentrant.
- }
PAINTSTRUCT paint_struct;
HDC hdc = ::BeginPaint(hWnd, &paint_struct);
if (paint_struct.rcPaint.right - paint_struct.rcPaint.left != 0 ||
@@ -564,7 +560,6 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
// repaint the window.
if (obj->client()->render_mode() == o3d::Client::RENDERMODE_CONTINUOUS) {
InvalidateRect(obj->GetHWnd(), NULL, FALSE);
- reentrance_count.decrement();
UpdateWindow(obj->GetHWnd());
}
@@ -691,10 +686,6 @@ NPError InitializePlugin() {
g_exception_manager->StartMonitoring();
}
- // Initialize the AtExitManager so that base singletons can be
- // destroyed properly.
- g_at_exit_manager.reset(new base::AtExitManager());
-
// Turn on the logging.
CommandLine::Init(0, NULL);
InitLogging(L"debug.log",
@@ -791,9 +782,6 @@ NPError OSCALL NP_Shutdown(void) {
CommandLine::Terminate();
- // Force all base singletons to be destroyed.
- g_at_exit_manager.reset(NULL);
-
// TODO : This is commented out until we can determine if
// it's safe to shutdown breakpad at this stage (Gears, for
// example, never deletes...)
@@ -891,10 +879,10 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window) {
DCHECK(obj->GetPluginHWnd());
DCHECK(obj->GetFullscreenHWnd());
DCHECK(obj->GetPluginHWnd() == hWnd);
-
+
// Exit full screen if the plugin window is being modified.
obj->CancelFullscreenDisplay();
-
+
return NPERR_NO_ERROR;
}
DCHECK(!obj->GetPluginHWnd());