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 <wtf/Threading.h> 35 36class WorkQueue::WorkItemQt : public QObject { 37 Q_OBJECT 38public: 39 WorkItemQt(WorkQueue* workQueue, const Function<void()>& function) 40 : m_queue(workQueue) 41 , m_source(0) 42 , m_signal(0) 43 , m_function(function) 44 { 45 } 46 47 WorkItemQt(WorkQueue* workQueue, QObject* source, const char* signal, const Function<void()>& function) 48 : m_queue(workQueue) 49 , m_source(source) 50 , m_signal(signal) 51 , m_function(function) 52 { 53 connect(m_source, m_signal, SLOT(execute()), Qt::QueuedConnection); 54 } 55 56 ~WorkItemQt() 57 { 58 m_queue->deref(); 59 } 60 61 Q_SLOT void execute() 62 { 63 m_function(); 64 } 65 66 Q_SLOT void executeAndDelete() 67 { 68 execute(); 69 delete this; 70 } 71 72 virtual void timerEvent(QTimerEvent*) 73 { 74 executeAndDelete(); 75 } 76 77 WorkQueue* m_queue; 78 QObject* m_source; 79 const char* m_signal; 80 Function<void()> m_function; 81}; 82 83QSocketNotifier* WorkQueue::registerSocketEventHandler(int socketDescriptor, QSocketNotifier::Type type, const Function<void()>& function) 84{ 85 ASSERT(m_workThread); 86 87 QSocketNotifier* notifier = new QSocketNotifier(socketDescriptor, type, 0); 88 notifier->setEnabled(false); 89 notifier->moveToThread(m_workThread); 90 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, notifier, SIGNAL(activated(int)), function); 91 itemQt->moveToThread(m_workThread); 92 QMetaObject::invokeMethod(notifier, "setEnabled", Q_ARG(bool, true)); 93 return notifier; 94} 95 96void WorkQueue::platformInitialize(const char*) 97{ 98 m_workThread = new QThread(); 99 m_workThread->start(); 100} 101 102void WorkQueue::platformInvalidate() 103{ 104 m_workThread->exit(); 105 m_workThread->wait(); 106 delete m_workThread; 107} 108 109void WorkQueue::dispatch(const Function<void()>& function) 110{ 111 ref(); 112 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, function); 113 itemQt->moveToThread(m_workThread); 114 QMetaObject::invokeMethod(itemQt, "executeAndDelete", Qt::QueuedConnection); 115} 116 117void WorkQueue::dispatchAfterDelay(const Function<void()>& function, double delayInSecond) 118{ 119 ref(); 120 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, function); 121 itemQt->startTimer(static_cast<int>(delayInSecond * 1000)); 122 itemQt->moveToThread(m_workThread); 123} 124 125void WorkQueue::dispatchOnTermination(WebKit::PlatformProcessIdentifier process, const Function<void()>& function) 126{ 127 WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, process, SIGNAL(finished(int, QProcess::ExitStatus)), function); 128 itemQt->moveToThread(m_workThread); 129} 130 131#include "WorkQueueQt.moc" 132