diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit2/Platform/qt | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit2/Platform/qt')
-rw-r--r-- | Source/WebKit2/Platform/qt/MappedMemoryPool.cpp | 114 | ||||
-rw-r--r-- | Source/WebKit2/Platform/qt/MappedMemoryPool.h | 109 | ||||
-rw-r--r-- | Source/WebKit2/Platform/qt/ModuleQt.cpp | 48 | ||||
-rw-r--r-- | Source/WebKit2/Platform/qt/RunLoopQt.cpp | 145 | ||||
-rw-r--r-- | Source/WebKit2/Platform/qt/SharedMemoryQt.cpp | 178 | ||||
-rw-r--r-- | Source/WebKit2/Platform/qt/WorkQueueQt.cpp | 132 |
6 files changed, 726 insertions, 0 deletions
diff --git a/Source/WebKit2/Platform/qt/MappedMemoryPool.cpp b/Source/WebKit2/Platform/qt/MappedMemoryPool.cpp new file mode 100644 index 0000000..d36d82b --- /dev/null +++ b/Source/WebKit2/Platform/qt/MappedMemoryPool.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2010 University of Szeged + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "MappedMemoryPool.h" + +#include "CleanupHandler.h" +#include "StdLibExtras.h" +#include <QDir> +#include <QIODevice> +#include <QTemporaryFile> + +namespace WebKit { + +MappedMemoryPool* MappedMemoryPool::theInstance = 0; + +MappedMemoryPool* MappedMemoryPool::instance() +{ + if (!theInstance) { + theInstance = new MappedMemoryPool; + + // Do not leave mapping files on the disk. + CleanupHandler::instance()->markForCleanup(theInstance); + } + + return theInstance; +} + +MappedMemoryPool::~MappedMemoryPool() +{ + CleanupHandler::instance()->unmark(theInstance); + + for (unsigned n = 0; n < m_pool.size(); ++n) { + MappedMemory& current = m_pool.at(n); + if (!current.file) + continue; + current.file->remove(); + delete current.file; + } + m_pool.clear(); +} + +MappedMemory* MappedMemoryPool::mapMemory(size_t size) +{ + for (unsigned n = 0; n < m_pool.size(); ++n) { + MappedMemory& current = m_pool.at(n); + if (current.dataSize >= size && current.isFree()) { + current.markUsed(); + return ¤t; + } + } + + MappedMemory newMap; + newMap.dataSize = size; + newMap.file = new QTemporaryFile(QDir::tempPath() + "/WebKit2UpdateChunk"); + newMap.file->open(QIODevice::ReadWrite); + newMap.fileName = newMap.file->fileName(); + newMap.file->resize(newMap.mapSize()); + newMap.mappedBytes = newMap.file->map(0, newMap.mapSize()); + newMap.file->close(); + newMap.markUsed(); + m_pool.append(newMap); + return &m_pool.last(); +} + +MappedMemory* MappedMemoryPool::mapFile(QString fileName, size_t size) +{ + for (unsigned n = 0; n < m_pool.size(); ++n) { + MappedMemory& current = m_pool.at(n); + if (current.fileName == fileName) { + ASSERT(!current.isFree()); + return ¤t; + } + } + + MappedMemory newMap; + newMap.file = new QFile(fileName); + newMap.fileName = fileName; + newMap.dataSize = size; + ASSERT(newMap.file->exists()); + ASSERT(newMap.file->size() >= newMap.mapSize()); + newMap.file->open(QIODevice::ReadWrite); + newMap.mappedBytes = newMap.file->map(0, newMap.mapSize()); + ASSERT(newMap.mappedBytes); + ASSERT(!newMap.isFree()); + newMap.file->close(); + m_pool.append(newMap); + return &m_pool.last(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/Platform/qt/MappedMemoryPool.h b/Source/WebKit2/Platform/qt/MappedMemoryPool.h new file mode 100644 index 0000000..8d6af8c --- /dev/null +++ b/Source/WebKit2/Platform/qt/MappedMemoryPool.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 University of Szeged + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MappedMemoryPool_h +#define MappedMemoryPool_h + +#include <QFile> +#include <QObject> +#include <wtf/StdLibExtras.h> +#include <wtf/Vector.h> + +namespace WebKit { + +class MappedMemoryPool; + +struct MappedMemory { + + QString mappedFileName() const + { + ASSERT(file); + ASSERT(mappedBytes); + return fileName; + } + + void markFree() + { + ASSERT(mappedBytes); + dataPtr->isFree = true; + } + + uchar* data() const + { + ASSERT(mappedBytes); + return dataPtr->bytes; + } + +private: + friend class MappedMemoryPool; + + MappedMemory() + : file(0) + , mappedBytes(0) + , dataSize(0) + { + } + + void markUsed() { dataPtr->isFree = false; } + + size_t mapSize() const { return dataSize + sizeof(Data); } + bool isFree() const { return dataPtr->isFree; } + + struct Data { + uint32_t isFree; // keep bytes aligned + uchar bytes[]; + }; + + QFile* file; + QString fileName; + union { + uchar* mappedBytes; + Data* dataPtr; + }; + size_t dataSize; +}; + +class MappedMemoryPool : QObject { + Q_OBJECT +public: + static MappedMemoryPool* instance(); + + MappedMemory* mapMemory(size_t size); + MappedMemory* mapFile(QString fileName, size_t size); + +private: + MappedMemoryPool() { } + ~MappedMemoryPool(); + + static MappedMemoryPool* theInstance; + + Vector<MappedMemory> m_pool; +}; + +} // namespace WebKit + +#endif // MappedMemoryPool_h diff --git a/Source/WebKit2/Platform/qt/ModuleQt.cpp b/Source/WebKit2/Platform/qt/ModuleQt.cpp new file mode 100644 index 0000000..8a68cf4 --- /dev/null +++ b/Source/WebKit2/Platform/qt/ModuleQt.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 University of Szeged. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Module.h" + +namespace WebKit { + +bool Module::load() +{ + m_lib.setFileName(static_cast<QString>(m_path)); + return m_lib.load(); +} + +void Module::unload() +{ + m_lib.unload(); +} + +void* Module::platformFunctionPointer(const char* functionName) const +{ + // Unfortunately QLibrary::resolve is not const. + return const_cast<QLibrary*>(&m_lib)->resolve(functionName); +} + +} diff --git a/Source/WebKit2/Platform/qt/RunLoopQt.cpp b/Source/WebKit2/Platform/qt/RunLoopQt.cpp new file mode 100644 index 0000000..d7d859d --- /dev/null +++ b/Source/WebKit2/Platform/qt/RunLoopQt.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "RunLoop.h" + +#include "WorkItem.h" + +#include <QApplication> +#include <QAbstractEventDispatcher> +#include <QObject> +#include <QMetaMethod> +#include <QMetaObject> +#include <QTimerEvent> + +class RunLoop::TimerObject : public QObject +{ + Q_OBJECT +public: + TimerObject(RunLoop* runLoop) : m_runLoop(runLoop) + { + int methodIndex = metaObject()->indexOfMethod("performWork()"); + m_method = metaObject()->method(methodIndex); + } + + Q_SLOT void performWork() { m_runLoop->performWork(); } + inline void wakeUp() { m_method.invoke(this, Qt::QueuedConnection); } + +protected: + virtual void timerEvent(QTimerEvent* event) + { + RunLoop::TimerBase::timerFired(m_runLoop, event->timerId()); + } + +private: + RunLoop* m_runLoop; + QMetaMethod m_method; +}; + +void RunLoop::run() +{ + QCoreApplication::exec(); +} + +void RunLoop::stop() +{ + QCoreApplication::exit(); +} + +RunLoop::RunLoop() + : m_timerObject(new TimerObject(this)) +{ +} + +RunLoop::~RunLoop() +{ + delete m_timerObject; +} + +void RunLoop::wakeUp() +{ + m_timerObject->wakeUp(); +} + +// RunLoop::Timer + +void RunLoop::TimerBase::timerFired(RunLoop* runLoop, int ID) +{ + TimerMap::iterator it = runLoop->m_activeTimers.find(ID); + ASSERT(it != runLoop->m_activeTimers.end()); + TimerBase* timer = it->second; + + if (!timer->m_isRepeating) { + // Stop the timer (calling stop would need another hash table lookup). + runLoop->m_activeTimers.remove(it); + runLoop->m_timerObject->killTimer(timer->m_ID); + timer->m_ID = 0; + } + + timer->fired(); +} + +RunLoop::TimerBase::TimerBase(RunLoop* runLoop) + : m_runLoop(runLoop) + , m_ID(0) + , m_isRepeating(false) +{ +} + +RunLoop::TimerBase::~TimerBase() +{ + stop(); +} + +void RunLoop::TimerBase::start(double nextFireInterval, bool repeat) +{ + stop(); + int millis = static_cast<int>(nextFireInterval * 1000); + m_isRepeating = repeat; + m_ID = m_runLoop->m_timerObject->startTimer(millis); + ASSERT(m_ID); + m_runLoop->m_activeTimers.set(m_ID, this); +} + +void RunLoop::TimerBase::stop() +{ + if (!m_ID) + return; + TimerMap::iterator it = m_runLoop->m_activeTimers.find(m_ID); + if (it == m_runLoop->m_activeTimers.end()) + return; + + m_runLoop->m_activeTimers.remove(it); + m_runLoop->m_timerObject->killTimer(m_ID); + m_ID = 0; +} + +bool RunLoop::TimerBase::isActive() const +{ + return m_ID; +} + +#include "RunLoopQt.moc" diff --git a/Source/WebKit2/Platform/qt/SharedMemoryQt.cpp b/Source/WebKit2/Platform/qt/SharedMemoryQt.cpp new file mode 100644 index 0000000..f5fecfc --- /dev/null +++ b/Source/WebKit2/Platform/qt/SharedMemoryQt.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (c) 2010 University of Szeged + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "SharedMemory.h" + +#include "ArgumentDecoder.h" +#include "ArgumentEncoder.h" +#include "CleanupHandler.h" +#include "WebCoreArgumentCoders.h" +#include <unistd.h> +#include <QCoreApplication> +#include <QLatin1String> +#include <QSharedMemory> +#include <QString> +#include <QUuid> +#include <wtf/Assertions.h> +#include <wtf/CurrentTime.h> + +namespace WebKit { + +SharedMemory::Handle::Handle() + : m_key() + , m_size(0) +{ +} + +SharedMemory::Handle::~Handle() +{ +} + +bool SharedMemory::Handle::isNull() const +{ + return m_key.isNull(); +} + +void SharedMemory::Handle::encode(CoreIPC::ArgumentEncoder* encoder) const +{ + encoder->encodeUInt64(m_size); + encoder->encode(m_key); + m_key = String(); +} + +bool SharedMemory::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& handle) +{ + ASSERT_ARG(handle, !handle.m_size); + ASSERT_ARG(handle, handle.m_key.isNull()); + + uint64_t size; + if (!decoder->decodeUInt64(size)) + return false; + + String key; + if (!decoder->decode(key)) + return false; + + handle.m_size = size; + handle.m_key = key; + + return true; +} + +static QString createUniqueKey() +{ + return QLatin1String("QWKSharedMemoryKey") + QUuid::createUuid().toString(); +} + +PassRefPtr<SharedMemory> SharedMemory::create(size_t size) +{ + RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); + QSharedMemory* impl = new QSharedMemory(createUniqueKey()); + bool created = impl->create(size); + ASSERT_UNUSED(created, created); + + sharedMemory->m_impl = impl; + sharedMemory->m_size = size; + sharedMemory->m_data = impl->data(); + + // Do not leave the shared memory segment behind. + CleanupHandler::instance()->markForCleanup(impl); + + return sharedMemory.release(); +} + +static inline QSharedMemory::AccessMode accessMode(SharedMemory::Protection protection) +{ + switch (protection) { + case SharedMemory::ReadOnly: + return QSharedMemory::ReadOnly; + case SharedMemory::ReadWrite: + return QSharedMemory::ReadWrite; + } + + ASSERT_NOT_REACHED(); + return QSharedMemory::ReadWrite; +} + +PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection) +{ + if (handle.isNull()) + return 0; + + QSharedMemory* impl = new QSharedMemory(QString(handle.m_key)); + bool attached = impl->attach(accessMode(protection)); + if (!attached) { + delete impl; + return 0; + } + + RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); + sharedMemory->m_impl = impl; + ASSERT(handle.m_size == impl->size()); + sharedMemory->m_size = handle.m_size; + sharedMemory->m_data = impl->data(); + + // Do not leave the shared memory segment behind. + CleanupHandler::instance()->markForCleanup(impl); + + return sharedMemory.release(); +} + +SharedMemory::~SharedMemory() +{ + if (CleanupHandler::instance()->hasStartedDeleting()) + return; + + CleanupHandler::instance()->unmark(m_impl); + delete m_impl; +} + +bool SharedMemory::createHandle(Handle& handle, Protection protection) +{ + ASSERT_ARG(handle, handle.m_key.isNull()); + ASSERT_ARG(handle, !handle.m_size); + + QString key = m_impl->key(); + if (key.isNull()) + return false; + handle.m_key = String(key); + handle.m_size = m_size; + + return true; +} + +unsigned SharedMemory::systemPageSize() +{ + static unsigned pageSize = 0; + + if (!pageSize) + pageSize = getpagesize(); + + return pageSize; +} + +} // namespace WebKit diff --git a/Source/WebKit2/Platform/qt/WorkQueueQt.cpp b/Source/WebKit2/Platform/qt/WorkQueueQt.cpp new file mode 100644 index 0000000..271984f --- /dev/null +++ b/Source/WebKit2/Platform/qt/WorkQueueQt.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WorkQueue.h" + +#include <QLocalSocket> +#include <QObject> +#include <QThread> +#include <wtf/Threading.h> +#include "NotImplemented.h" + +class WorkQueue::WorkItemQt : public QObject { + Q_OBJECT +public: + WorkItemQt(WorkQueue* workQueue, WorkItem* workItem) + : m_queue(workQueue) + , m_source(0) + , m_signal(0) + , m_workItem(workItem) + { + } + + WorkItemQt(WorkQueue* workQueue, QObject* source, const char* signal, WorkItem* workItem) + : m_queue(workQueue) + , m_source(source) + , m_signal(signal) + , m_workItem(workItem) + { + connect(m_source, m_signal, SLOT(execute()), Qt::QueuedConnection); + } + + ~WorkItemQt() + { + delete m_workItem; + } + + Q_SLOT void execute() + { + if (m_queue->m_isValid) + m_workItem->execute(); + } + + virtual void timerEvent(QTimerEvent*) + { + execute(); + delete this; + } + + WorkQueue* m_queue; + QObject* m_source; + const char* m_signal; + WorkItem* m_workItem; +}; + +void WorkQueue::connectSignal(QObject* o, const char* signal, PassOwnPtr<WorkItem> workItem) +{ + WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, o, signal, workItem.leakPtr()); + itemQt->moveToThread(m_workThread); + m_signalListeners.add(o, itemQt); +} + +void WorkQueue::disconnectSignal(QObject* o, const char* name) +{ + HashMap<QObject*, WorkItemQt*>::iterator it = m_signalListeners.find(o); + for (; it != m_signalListeners.end(); ++it) { + if (strcmp(it->second->m_signal, name)) + continue; + delete it->second; + m_signalListeners.remove(it); + return; + } +} + +void WorkQueue::moveSocketToWorkThread(QLocalSocket* socket) +{ + ASSERT(m_workThread); + ASSERT(socket); + + socket->setParent(0); + socket->moveToThread(m_workThread); +} + +void WorkQueue::platformInitialize(const char*) +{ + m_workThread = new QThread(); + m_workThread->start(); +} + +void WorkQueue::platformInvalidate() +{ + m_workThread->exit(); + m_workThread->wait(); + delete m_workThread; + deleteAllValues(m_signalListeners); +} + +void WorkQueue::scheduleWork(PassOwnPtr<WorkItem> item) +{ + WorkQueue::WorkItemQt* itemQt = new WorkQueue::WorkItemQt(this, item.leakPtr()); + itemQt->startTimer(0); + itemQt->moveToThread(m_workThread); +} + +void WorkQueue::scheduleWorkAfterDelay(PassOwnPtr<WorkItem>, double) +{ + notImplemented(); +} + +#include "WorkQueueQt.moc" |