1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include "WorkQueue.h"
29
30 #include <QLocalSocket>
31 #include <QObject>
32 #include <QThread>
33 #include <QProcess>
34 #include <WebCore/NotImplemented.h>
35 #include <wtf/Threading.h>
36
37 class WorkQueue::WorkItemQt : public QObject {
38 Q_OBJECT
39 public:
WorkItemQt(WorkQueue * workQueue,WorkItem * workItem)40 WorkItemQt(WorkQueue* workQueue, WorkItem* workItem)
41 : m_queue(workQueue)
42 , m_source(0)
43 , m_signal(0)
44 , m_workItem(workItem)
45 {
46 }
47
WorkItemQt(WorkQueue * workQueue,QObject * source,const char * signal,WorkItem * workItem)48 WorkItemQt(WorkQueue* workQueue, QObject* source, const char* signal, WorkItem* workItem)
49 : m_queue(workQueue)
50 , m_source(source)
51 , m_signal(signal)
52 , m_workItem(workItem)
53 {
54 connect(m_source, m_signal, SLOT(execute()), Qt::QueuedConnection);
55 }
56
~WorkItemQt()57 ~WorkItemQt()
58 {
59 delete m_workItem;
60 }
61
execute()62 Q_SLOT void execute()
63 {
64 if (m_queue->m_isValid)
65 m_workItem->execute();
66 }
67
timerEvent(QTimerEvent *)68 virtual void timerEvent(QTimerEvent*)
69 {
70 execute();
71 delete this;
72 }
73
74 WorkQueue* m_queue;
75 QObject* m_source;
76 const char* m_signal;
77 WorkItem* m_workItem;
78 };
79
registerSocketEventHandler(int socketDescriptor,QSocketNotifier::Type type,PassOwnPtr<WorkItem> workItem)80 QSocketNotifier* WorkQueue::registerSocketEventHandler(int socketDescriptor, QSocketNotifier::Type type, PassOwnPtr<WorkItem> workItem)
81 {
82 ASSERT(m_workThread);
83
84 QSocketNotifier* notifier = new QSocketNotifier(socketDescriptor, type, 0);
85 notifier->setEnabled(false);
86 notifier->moveToThread(m_workThread);
87 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, notifier, SIGNAL(activated(int)), workItem.leakPtr());
88 itemQt->moveToThread(m_workThread);
89 notifier->setEnabled(true);
90 return notifier;
91 }
92
platformInitialize(const char *)93 void WorkQueue::platformInitialize(const char*)
94 {
95 m_workThread = new QThread();
96 m_workThread->start();
97 }
98
platformInvalidate()99 void WorkQueue::platformInvalidate()
100 {
101 m_workThread->exit();
102 m_workThread->wait();
103 delete m_workThread;
104 deleteAllValues(m_signalListeners);
105 }
106
scheduleWork(PassOwnPtr<WorkItem> item)107 void WorkQueue::scheduleWork(PassOwnPtr<WorkItem> item)
108 {
109 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, item.leakPtr());
110 itemQt->startTimer(0);
111 itemQt->moveToThread(m_workThread);
112 }
113
scheduleWorkAfterDelay(PassOwnPtr<WorkItem> item,double delayInSecond)114 void WorkQueue::scheduleWorkAfterDelay(PassOwnPtr<WorkItem> item, double delayInSecond)
115 {
116 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, item.leakPtr());
117 itemQt->startTimer(static_cast<int>(delayInSecond * 1000));
118 itemQt->moveToThread(m_workThread);
119 }
120
scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier process,PassOwnPtr<WorkItem> workItem)121 void WorkQueue::scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier process, PassOwnPtr<WorkItem> workItem)
122 {
123 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, process, SIGNAL(finished(int, QProcess::ExitStatus)), workItem.leakPtr());
124 itemQt->moveToThread(m_workThread);
125 }
126
127 #include "WorkQueueQt.moc"
128