1dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch/*
2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2010 Google Inc. All rights reserved.
3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
4dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Redistribution and use in source and binary forms, with or without
5dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * modification, are permitted provided that the following conditions are
6dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * met:
7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
8dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *     * Redistributions of source code must retain the above copyright
9dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * notice, this list of conditions and the following disclaimer.
10dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *     * Redistributions in binary form must reproduce the above
11dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
12dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * in the documentation and/or other materials provided with the
13dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * distribution.
14dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
15dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * contributors may be used to endorse or promote products derived from
16dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * this software without specific prior written permission.
17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
18dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch */
30dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
31dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "config.h"
32dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "ActiveDOMCallback.h"
33dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
34dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "ActiveDOMObject.h"
35dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "ScriptExecutionContext.h"
36dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/PassOwnPtr.h>
37dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/ThreadingPrimitives.h>
38dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
39dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochnamespace WebCore {
40dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
41dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochstatic void destroyOnContextThread(PassOwnPtr<ActiveDOMObjectCallbackImpl>);
42dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
43dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochclass DestroyOnContextThreadTask : public ScriptExecutionContext::Task {
44dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochpublic:
45dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    static PassOwnPtr<DestroyOnContextThreadTask> create(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl)
46dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
47dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return adoptPtr(new DestroyOnContextThreadTask(impl));
48dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
49dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
50dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    virtual void performTask(ScriptExecutionContext*)
51dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
52dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        destroyOnContextThread(m_impl.release());
53dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
54dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
55dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochprivate:
56dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    DestroyOnContextThreadTask(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl)
57dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        : m_impl(impl)
58dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
59dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
60dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
61dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    OwnPtr<ActiveDOMObjectCallbackImpl> m_impl;
62dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch};
63dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
64dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochclass ActiveDOMObjectCallbackImpl : public ActiveDOMObject {
65dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochpublic:
66dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    ActiveDOMObjectCallbackImpl(ScriptExecutionContext* context)
67dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        : ActiveDOMObject(context, this)
68dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , m_suspended(false)
69dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , m_stopped(false)
70dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
71dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
72dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
73dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    virtual void contextDestroyed()
74dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
75dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
76dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ActiveDOMObject::contextDestroyed();
77dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
78dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    virtual bool canSuspend() const { return false; }
7968513a70bcd92384395513322f1b801e7bf9c729Steve Block    virtual void suspend(ReasonForSuspension)
80dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
81dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
82dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        m_suspended = true;
83dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
84dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    virtual void resume()
85dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
86dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
87dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        m_suspended = false;
88dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
89dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    virtual void stop()
90dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
91dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
92dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        m_stopped = true;
93dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
94dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool canInvokeCallback()
95dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
96dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
97dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return (!m_suspended && !m_stopped);
98dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
99dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    ScriptExecutionContext* scriptExecutionContext()
100dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
101dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        MutexLocker locker(m_mutex);
102dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return ActiveDOMObject::scriptExecutionContext();
103dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
104dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    Mutex& mutex() { return m_mutex; }
105dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
106dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochprivate:
107dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    Mutex m_mutex;
108dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool m_suspended;
109dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool m_stopped;
110dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch};
111dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
112dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochstatic void destroyOnContextThread(PassOwnPtr<ActiveDOMObjectCallbackImpl> impl)
113dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
114dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    OwnPtr<ActiveDOMObjectCallbackImpl> implOwnPtr = impl;
115dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
116dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    ScriptExecutionContext* context = implOwnPtr->scriptExecutionContext();
117dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    MutexLocker locker(implOwnPtr->mutex());
118dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (context && !context->isContextThread())
119dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        context->postTask(DestroyOnContextThreadTask::create(implOwnPtr.release()));
120dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
121dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
122dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochActiveDOMCallback::ActiveDOMCallback(ScriptExecutionContext* context)
123dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    : m_impl(new ActiveDOMObjectCallbackImpl(context))
124dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
125dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
126dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
127dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochActiveDOMCallback::~ActiveDOMCallback()
128dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
129dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    destroyOnContextThread(m_impl.release());
130dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
131dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
132dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochbool ActiveDOMCallback::canInvokeCallback() const
133dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
134dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    return m_impl->canInvokeCallback();
135dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
136dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
137dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochScriptExecutionContext* ActiveDOMCallback::scriptExecutionContext() const
138dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
139dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    return m_impl->scriptExecutionContext();
140dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
141dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
142dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch} // namespace WebCore
143