Commit ddf6794f authored by ap@webkit.org's avatar ap@webkit.org

Reviewed by Maciej Stachowiak.

        https://bugs.webkit.org/show_bug.cgi?id=22083
        MessageEvents cannot be used across threads

        * dom/Event.idl:
        * dom/MessageEvent.idl:
        Add a NoStaticTables attribute - MessageEvent is used in worker threads, so static tables
        won't work.

        * dom/MessagePort.cpp:
        (WebCore::MessagePort::EventData::EventData):
        (WebCore::MessagePort::EventData::~EventData):
        (WebCore::MessagePort::clone):
        (WebCore::MessagePort::postMessage):
        (WebCore::MessagePort::startConversation):
        (WebCore::MessagePort::dispatchMessages):
        * dom/MessagePort.h:
        Don't create a MessageEvent until dispatch time - messages can be posted across threads,
        but MessageEvents are tied to the thread that they were created in.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@38151 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 90b52e84
2008-11-05 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Maciej Stachowiak.
https://bugs.webkit.org/show_bug.cgi?id=22083
MessageEvents cannot be used across threads
* dom/Event.idl:
* dom/MessageEvent.idl:
Add a NoStaticTables attribute - MessageEvent is used in worker threads, so static tables
won't work.
* dom/MessagePort.cpp:
(WebCore::MessagePort::EventData::EventData):
(WebCore::MessagePort::EventData::~EventData):
(WebCore::MessagePort::clone):
(WebCore::MessagePort::postMessage):
(WebCore::MessagePort::startConversation):
(WebCore::MessagePort::dispatchMessages):
* dom/MessagePort.h:
Don't create a MessageEvent until dispatch time - messages can be posted across threads,
but MessageEvents are tied to the thread that they were created in.
2008-11-05 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin Adler.
......@@ -23,6 +23,7 @@ module events {
// Introduced in DOM Level 2:
interface [
GenerateConstructor,
NoStaticTables,
ObjCCustomInternalImpl,
InterfaceUUID=D17495FA-ACAD-4d27-9362-E19E057B189D,
ImplementationUUID=CFDCDDB2-5B3F-412d-BDA4-80B23C721549
......
......@@ -27,7 +27,8 @@
module events {
interface [
GenerateConstructor
GenerateConstructor,
NoStaticTables
] MessageEvent : Event {
readonly attribute DOMString data;
......
......@@ -62,6 +62,22 @@ private:
RefPtr<MessagePort> m_port;
};
MessagePort::EventData::EventData()
{
}
MessagePort::EventData::EventData(const String& message, PassRefPtr<DOMWindow> window, PassRefPtr<MessagePort> messagePort)
: message(message.copy())
, window(window)
, messagePort(messagePort)
{
ASSERT(!this->window || isMainThread());
}
MessagePort::EventData::~EventData()
{
}
MessagePort::MessagePort(ScriptExecutionContext* scriptExecutionContext)
: m_entangledPort(0)
, m_queueIsOpen(false)
......@@ -93,9 +109,9 @@ PassRefPtr<MessagePort> MessagePort::clone(ScriptExecutionContext* newOwner, Exc
// Move all the events in the port message queue of original port to the port message queue of new port, if any, leaving the new port's port message queue in its initial closed state.
// If events are posted (e.g. from a worker thread) while this code is executing, there is no guarantee whether they end up in the original or new port's message queue.
RefPtr<Event> event;
while (m_messageQueue.tryGetMessage(event))
newPort->m_messageQueue.append(event);
EventData eventData;
while (m_messageQueue.tryGetMessage(eventData))
newPort->m_messageQueue.append(eventData);
entangle(remotePort.get(), newPort.get()); // The port object will be unentangled.
return newPort;
......@@ -124,7 +140,7 @@ void MessagePort::postMessage(const String& message, MessagePort* dataPort, Exce
DOMWindow* window = (m_scriptExecutionContext->isDocument() && m_entangledPort->m_scriptExecutionContext->isDocument()) ?
static_cast<Document*>(m_scriptExecutionContext)->domWindow() : 0;
m_entangledPort->m_messageQueue.append(MessageEvent::create(message, "", "", window, newMessagePort.get()));
m_entangledPort->m_messageQueue.append(EventData(message, window, newMessagePort));
if (m_entangledPort->m_queueIsOpen)
m_entangledPort->m_scriptExecutionContext->processMessagePortMessagesSoon();
}
......@@ -140,7 +156,7 @@ PassRefPtr<MessagePort> MessagePort::startConversation(ScriptExecutionContext* s
DOMWindow* window = (m_scriptExecutionContext->isDocument() && m_entangledPort->m_scriptExecutionContext->isDocument()) ?
static_cast<Document*>(m_scriptExecutionContext)->domWindow() : 0;
m_entangledPort->m_messageQueue.append(MessageEvent::create(message, "", "", window, port2.get()));
m_entangledPort->m_messageQueue.append(EventData(message, window, port2));
if (m_entangledPort->m_queueIsOpen)
m_entangledPort->m_scriptExecutionContext->processMessagePortMessagesSoon();
return port1;
......@@ -207,10 +223,12 @@ void MessagePort::dispatchMessages()
// Messages for contexts that are not fully active get dispatched too, but JSAbstractEventListener::handleEvent() doesn't call handlers for these.
ASSERT(queueIsOpen());
RefPtr<Event> evt;
while (m_messageQueue.tryGetMessage(evt)) {
EventData eventData;
while (m_messageQueue.tryGetMessage(eventData)) {
ASSERT(!eventData.window || isMainThread());
ASSERT(!eventData.window || scriptExecutionContext()->isDocument());
ASSERT(evt->type() == eventNames().messageEvent);
RefPtr<Event> evt = MessageEvent::create(eventData.message, "", "", eventData.window, eventData.messagePort);
if (m_onMessageListener) {
evt->setTarget(this);
......
......@@ -41,6 +41,7 @@
namespace WebCore {
class AtomicStringImpl;
class DOMWindow;
class Event;
class Frame;
class ScriptExecutionContext;
......@@ -108,7 +109,17 @@ namespace WebCore {
void dispatchCloseEvent();
MessagePort* m_entangledPort;
MessageQueue<RefPtr<Event> > m_messageQueue;
struct EventData {
EventData();
EventData(const String&, PassRefPtr<DOMWindow>, PassRefPtr<MessagePort>);
~EventData();
String message;
RefPtr<DOMWindow> window;
RefPtr<MessagePort> messagePort;
};
MessageQueue<EventData> m_messageQueue;
bool m_queueIsOpen;
ScriptExecutionContext* m_scriptExecutionContext;
......
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