Commit f1fd1c90 authored by andersca@apple.com's avatar andersca@apple.com

2009-02-06 Anders Carlsson <andersca@apple.com>

        Reviewed by Sam Weinig.

        <rdar://problem/6562220> 
        CrashTracer: [USER] 21 crashes in Safari at com.apple.WebKit • WebKit::NetscapePluginHostProxy::port
        
        Make the handling of crashes in the plug-in host more robust.
        
        * Plugins/Hosted/NetscapePluginHostProxy.h:
        Add m_portSet.
        
        * Plugins/Hosted/NetscapePluginHostProxy.mm:
        (WebKit::NetscapePluginHostProxy::NetscapePluginHostProxy):
        Initialize m_portSet.
        
        (WebKit::NetscapePluginHostProxy::~NetscapePluginHostProxy):
        Free m_portSet.
        
        (WebKit::NetscapePluginHostProxy::processRequests):
        Listen for messages on the port set. If we get a message to the port death notification port,
        then call pluginHostDied. Otherwise, process the message.
        
        * Plugins/Hosted/NetscapePluginInstanceProxy.h:
        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
        (WebKit::NetscapePluginInstanceProxy::cleanup):
        Factor code that should be shared between destroy() and pluginHostDied() into cleanup.
        
        (WebKit::NetscapePluginInstanceProxy::destroy):
        Call cleanup().
        
        (WebKit::NetscapePluginInstanceProxy::pluginHostDied):
        Call cleanup().
        
        (WebKit::NetscapePluginInstanceProxy::processRequestsAndWaitForReply):
        Call NetscapePluginHostProxy::processRequests.
        
        * Plugins/Hosted/ProxyInstance.mm:
        (WebKit::ProxyInstance::invalidate):
        Add a null check for the host proxy.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@40733 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9583c054
2009-02-06 Anders Carlsson <andersca@apple.com>
Reviewed by Sam Weinig.
<rdar://problem/6562220>
CrashTracer: [USER] 21 crashes in Safari at com.apple.WebKit • WebKit::NetscapePluginHostProxy::port
Make the handling of crashes in the plug-in host more robust.
* Plugins/Hosted/NetscapePluginHostProxy.h:
Add m_portSet.
* Plugins/Hosted/NetscapePluginHostProxy.mm:
(WebKit::NetscapePluginHostProxy::NetscapePluginHostProxy):
Initialize m_portSet.
(WebKit::NetscapePluginHostProxy::~NetscapePluginHostProxy):
Free m_portSet.
(WebKit::NetscapePluginHostProxy::processRequests):
Listen for messages on the port set. If we get a message to the port death notification port,
then call pluginHostDied. Otherwise, process the message.
* Plugins/Hosted/NetscapePluginInstanceProxy.h:
* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::cleanup):
Factor code that should be shared between destroy() and pluginHostDied() into cleanup.
(WebKit::NetscapePluginInstanceProxy::destroy):
Call cleanup().
(WebKit::NetscapePluginInstanceProxy::pluginHostDied):
Call cleanup().
(WebKit::NetscapePluginInstanceProxy::processRequestsAndWaitForReply):
Call NetscapePluginHostProxy::processRequests.
* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invalidate):
Add a null check for the host proxy.
2009-02-06 Dan Bernstein <mitz@apple.com>
- try to fix the Tiger build
......
......@@ -54,6 +54,8 @@ public:
void applicationDidBecomeActive();
bool processRequests();
private:
~NetscapePluginHostProxy();
void pluginHostDied();
......@@ -67,6 +69,8 @@ private:
PluginInstanceMap m_instances;
mach_port_t m_clientPort;
mach_port_t m_portSet;
#ifdef USE_LIBDISPATCH
dispatch_source_t m_clientPortSource;
#else
......
......@@ -61,6 +61,7 @@ static PluginProxyMap& pluginProxyMap()
NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN)
: m_clientPort(clientPort)
, m_portSet(MACH_PORT_NULL)
, m_pluginHostPort(pluginHostPort)
, m_isModal(false)
, m_menuBarIsVisible(true)
......@@ -94,6 +95,13 @@ NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_po
NetscapePluginHostProxy::~NetscapePluginHostProxy()
{
pluginProxyMap().remove(m_clientPort);
// Free the port set
if (m_portSet) {
mach_port_extract_member(mach_task_self(), m_clientPort, m_portSet);
mach_port_extract_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
mach_port_destroy(mach_task_self(), m_portSet);
}
ASSERT(m_clientPortSource);
#ifdef USE_LIBDISPATCH
......@@ -220,6 +228,51 @@ void NetscapePluginHostProxy::setModal(bool modal)
endModal();
}
bool NetscapePluginHostProxy::processRequests()
{
if (!m_portSet) {
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &m_portSet);
mach_port_insert_member(mach_task_self(), m_clientPort, m_portSet);
mach_port_insert_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
}
char buffer[4096];
mach_msg_header_t* msg = reinterpret_cast<mach_msg_header_t*>(buffer);
kern_return_t kr = mach_msg(msg, MACH_RCV_MSG, 0, sizeof(buffer), m_portSet, 0, MACH_PORT_NULL);
if (kr != KERN_SUCCESS) {
LOG_ERROR("Could not receive mach message, error %x", kr);
return false;
}
if (msg->msgh_local_port == m_clientPort) {
__ReplyUnion__WKWebKitPluginClient_subsystem reply;
mach_msg_header_t* replyHeader = reinterpret_cast<mach_msg_header_t*>(&reply);
if (WebKitPluginClient_server(msg, replyHeader) && replyHeader->msgh_remote_port != MACH_PORT_NULL) {
kr = mach_msg(replyHeader, MACH_SEND_MSG, replyHeader->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
if (kr != KERN_SUCCESS) {
LOG_ERROR("Could not send mach message, error %x", kr);
return false;
}
}
return true;
}
if (msg->msgh_local_port == CFMachPortGetPort(m_deadNameNotificationPort.get())) {
ASSERT(msg->msgh_id == MACH_NOTIFY_DEAD_NAME);
pluginHostDied();
return false;
}
ASSERT_NOT_REACHED();
return false;
}
} // namespace WebKit
using namespace WebKit;
......
......@@ -222,6 +222,8 @@ private:
void stopAllStreams();
void processRequestsAndWaitForReply();
void cleanup();
NetscapePluginHostProxy* m_pluginHostProxy;
WebHostedNetscapePluginView *m_pluginView;
......
......@@ -126,16 +126,14 @@ void NetscapePluginInstanceProxy::stopAllStreams()
streamsCopy[i]->stop();
}
void NetscapePluginInstanceProxy::destroy()
void NetscapePluginInstanceProxy::cleanup()
{
stopAllStreams();
_WKPHDestroyPluginInstance(m_pluginHostProxy->port(), m_pluginID);
// Clear the object map, this will cause any outstanding JS objects that the plug-in had a reference to
// to go away when the next garbage collection takes place.
m_objects.clear();
if (Frame* frame = core([m_pluginView webFrame]))
frame->script()->cleanupScriptObjectsForPlugin(m_pluginView);
......@@ -146,7 +144,14 @@ void NetscapePluginInstanceProxy::destroy()
ProxyInstanceSet::const_iterator end = instances.end();
for (ProxyInstanceSet::const_iterator it = instances.begin(); it != end; ++it)
(*it)->invalidate();
}
void NetscapePluginInstanceProxy::destroy()
{
_WKPHDestroyPluginInstance(m_pluginHostProxy->port(), m_pluginID);
cleanup();
m_pluginHostProxy->removePluginInstance(this);
m_pluginHostProxy = 0;
}
......@@ -163,9 +168,9 @@ void NetscapePluginInstanceProxy::disconnectStream(HostedNetscapePluginStream* s
void NetscapePluginInstanceProxy::pluginHostDied()
{
stopAllStreams();
m_pluginHostProxy = 0;
cleanup();
[m_pluginView pluginHostDied];
m_pluginView = nil;
......@@ -467,8 +472,7 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
void NetscapePluginInstanceProxy::processRequestsAndWaitForReply()
{
while (!m_currentReply.get()) {
kern_return_t kr = mach_msg_server_once(WebKitPluginClient_server, WKWebKitPluginClient_subsystem.maxsize + MAX_TRAILER_SIZE, m_pluginHostProxy->clientPort(), 0);
if (kr != KERN_SUCCESS) {
if (!m_pluginHostProxy->processRequests()) {
m_currentReply.reset();
break;
}
......
......@@ -311,8 +311,9 @@ void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValuePt
void ProxyInstance::invalidate()
{
_WKPHNPObjectRelease(m_instanceProxy->hostProxy()->port(),
m_instanceProxy->pluginID(), m_objectID);
if (NetscapePluginHostProxy* hostProxy = m_instanceProxy->hostProxy())
_WKPHNPObjectRelease(hostProxy->port(),
m_instanceProxy->pluginID(), m_objectID);
m_instanceProxy = 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment