diff options
author | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-03 19:49:35 +0000 |
---|---|---|
committer | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-03 19:49:35 +0000 |
commit | 91240c947358b33cc19c0923a06d116ab36737dd (patch) | |
tree | 7897c99ad9b41d7735c7a42e0ea75fe6f76760b3 /o3d/plugin | |
parent | 2e25a9f4152a90a179ad37206bff79e1198379d7 (diff) | |
download | chromium_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.scons | 9 | ||||
-rw-r--r-- | o3d/plugin/cross/main_thread_task_poster.cc | 64 | ||||
-rw-r--r-- | o3d/plugin/cross/main_thread_task_poster.h | 57 | ||||
-rw-r--r-- | o3d/plugin/cross/o3d_glue.cc | 61 | ||||
-rw-r--r-- | o3d/plugin/cross/o3d_glue.h | 3 | ||||
-rw-r--r-- | o3d/plugin/idl/archive_request.idl | 11 | ||||
-rw-r--r-- | o3d/plugin/idl/file_request.idl | 3 | ||||
-rw-r--r-- | o3d/plugin/linux/main_linux.cc | 16 | ||||
-rw-r--r-- | o3d/plugin/mac/main_mac.mm | 16 | ||||
-rw-r--r-- | o3d/plugin/npapi_host_control/win/host_control.cc | 11 | ||||
-rw-r--r-- | o3d/plugin/npapi_host_control/win/host_control.h | 5 | ||||
-rw-r--r-- | o3d/plugin/npapi_host_control/win/np_browser_proxy.cc | 19 | ||||
-rw-r--r-- | o3d/plugin/npapi_host_control/win/np_browser_proxy.h | 4 | ||||
-rw-r--r-- | o3d/plugin/plugin.gyp | 2 | ||||
-rw-r--r-- | o3d/plugin/win/main_win.cc | 28 |
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()); |