Home | History | Annotate | Download | only in workers
      1 /*
      2  * Copyright (C) 2010 Google Inc. All Rights Reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  *
     25  */
     26 
     27 #include "config.h"
     28 #include "core/workers/WorkerEventQueue.h"
     29 
     30 #include "core/dom/ExecutionContext.h"
     31 #include "core/dom/ExecutionContextTask.h"
     32 #include "core/events/Event.h"
     33 #include "core/inspector/InspectorInstrumentation.h"
     34 
     35 namespace blink {
     36 
     37 PassOwnPtrWillBeRawPtr<WorkerEventQueue> WorkerEventQueue::create(ExecutionContext* context)
     38 {
     39     return adoptPtrWillBeNoop(new WorkerEventQueue(context));
     40 }
     41 
     42 WorkerEventQueue::WorkerEventQueue(ExecutionContext* context)
     43     : m_executionContext(context)
     44     , m_isClosed(false)
     45 {
     46 }
     47 
     48 WorkerEventQueue::~WorkerEventQueue()
     49 {
     50     ASSERT(m_eventTaskMap.isEmpty());
     51 }
     52 
     53 void WorkerEventQueue::trace(Visitor* visitor)
     54 {
     55 #if ENABLE(OILPAN)
     56     visitor->trace(m_executionContext);
     57     visitor->trace(m_eventTaskMap);
     58 #endif
     59     EventQueue::trace(visitor);
     60 }
     61 
     62 class WorkerEventQueue::EventDispatcherTask : public ExecutionContextTask {
     63 public:
     64     static PassOwnPtr<EventDispatcherTask> create(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue)
     65     {
     66         return adoptPtr(new EventDispatcherTask(event, eventQueue));
     67     }
     68 
     69     virtual ~EventDispatcherTask()
     70     {
     71         if (m_event)
     72             m_eventQueue->removeEvent(m_event.get());
     73     }
     74 
     75     void dispatchEvent(ExecutionContext*, PassRefPtrWillBeRawPtr<Event> event)
     76     {
     77         event->target()->dispatchEvent(event);
     78     }
     79 
     80     virtual void performTask(ExecutionContext* context)
     81     {
     82         if (m_isCancelled)
     83             return;
     84         m_eventQueue->removeEvent(m_event.get());
     85         dispatchEvent(context, m_event);
     86         m_event.clear();
     87     }
     88 
     89     void cancel()
     90     {
     91         m_isCancelled = true;
     92         m_event.clear();
     93     }
     94 
     95 private:
     96     EventDispatcherTask(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue)
     97         : m_event(event)
     98         , m_eventQueue(eventQueue)
     99         , m_isCancelled(false)
    100     {
    101     }
    102 
    103     RefPtrWillBePersistent<Event> m_event;
    104     WorkerEventQueue* m_eventQueue;
    105     bool m_isCancelled;
    106 };
    107 
    108 void WorkerEventQueue::removeEvent(Event* event)
    109 {
    110     InspectorInstrumentation::didRemoveEvent(event->target(), event);
    111     m_eventTaskMap.remove(event);
    112 }
    113 
    114 bool WorkerEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr<Event> prpEvent)
    115 {
    116     if (m_isClosed)
    117         return false;
    118     RefPtrWillBeRawPtr<Event> event = prpEvent;
    119     InspectorInstrumentation::didEnqueueEvent(event->target(), event.get());
    120     OwnPtr<EventDispatcherTask> task = EventDispatcherTask::create(event, this);
    121     m_eventTaskMap.add(event.release(), task.get());
    122     m_executionContext->postTask(task.release());
    123     return true;
    124 }
    125 
    126 bool WorkerEventQueue::cancelEvent(Event* event)
    127 {
    128     EventDispatcherTask* task = m_eventTaskMap.get(event);
    129     if (!task)
    130         return false;
    131     task->cancel();
    132     removeEvent(event);
    133     return true;
    134 }
    135 
    136 void WorkerEventQueue::close()
    137 {
    138     m_isClosed = true;
    139     for (EventTaskMap::iterator it = m_eventTaskMap.begin(); it != m_eventTaskMap.end(); ++it) {
    140         Event* event = it->key.get();
    141         EventDispatcherTask* task = it->value;
    142         InspectorInstrumentation::didRemoveEvent(event->target(), event);
    143         task->cancel();
    144     }
    145     m_eventTaskMap.clear();
    146 }
    147 
    148 }
    149