summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/cfsocketnotifier
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@theqtcompany.com>2015-06-30 13:28:31 +0200
committerTor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>2015-10-16 18:07:32 +0000
commitc751cef8d6fe3e6bee1ec9a0466094b3255ca037 (patch)
tree5726e6c2da79343d03bae35978efe3a13f63822c /src/platformsupport/cfsocketnotifier
parent40b4c305d82e75d23842348a537972a0d2f15887 (diff)
Move QEventDispatcherCoreFoundation to QtCore
Export it for use by the iOS platform plugin. Also move QCFSocketNotifier, and export for use by the Cocoa platform plugin. This is a pure code move with no intended behavior changes, in anticipation of using the Core Foundation event dispatcher as the default Qt Core event dispatcher on OS X. Change-Id: I43677d2f6f3c1d0ed0415c964225aa97d2f13078 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
Diffstat (limited to 'src/platformsupport/cfsocketnotifier')
-rw-r--r--src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri4
-rw-r--r--src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp303
-rw-r--r--src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h105
3 files changed, 0 insertions, 412 deletions
diff --git a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
deleted file mode 100644
index 9a19d3c278..0000000000
--- a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-mac {
- HEADERS += $$PWD/qcfsocketnotifier_p.h
- SOURCES += $$PWD/qcfsocketnotifier.cpp
-}
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp
deleted file mode 100644
index c58e0ea78d..0000000000
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcfsocketnotifier_p.h"
-#include <QtGui/qguiapplication.h>
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qthread.h>
-
-
-/**************************************************************************
- Socket Notifiers
- *************************************************************************/
-void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
- const void *, void *info)
-{
-
- QCFSocketNotifier *cfSocketNotifier = static_cast<QCFSocketNotifier *>(info);
- int nativeSocket = CFSocketGetNative(s);
- MacSocketInfo *socketInfo = cfSocketNotifier->macSockets.value(nativeSocket);
- QEvent notifierEvent(QEvent::SockAct);
-
- // There is a race condition that happen where we disable the notifier and
- // the kernel still has a notification to pass on. We then get this
- // notification after we've successfully disabled the CFSocket, but our Qt
- // notifier is now gone. The upshot is we have to check the notifier
- // every time.
- if (callbackType == kCFSocketReadCallBack) {
- if (socketInfo->readNotifier && socketInfo->readEnabled) {
- socketInfo->readEnabled = false;
- QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
- }
- } else if (callbackType == kCFSocketWriteCallBack) {
- if (socketInfo->writeNotifier && socketInfo->writeEnabled) {
- socketInfo->writeEnabled = false;
- QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
- }
- }
-
- if (cfSocketNotifier->maybeCancelWaitForMoreEvents)
- cfSocketNotifier->maybeCancelWaitForMoreEvents(cfSocketNotifier->eventDispatcher);
-}
-
-/*
- Adds a loop source for the given socket to the current run loop.
-*/
-CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
-{
- CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
- if (!loopSource)
- return 0;
-
- CFRunLoopAddSource(CFRunLoopGetMain(), loopSource, kCFRunLoopCommonModes);
- return loopSource;
-}
-
-/*
- Removes the loop source for the given socket from the current run loop.
-*/
-void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
-{
- Q_ASSERT(runloop);
- CFRunLoopRemoveSource(CFRunLoopGetMain(), runloop, kCFRunLoopCommonModes);
- CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
- CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
-}
-
-QCFSocketNotifier::QCFSocketNotifier()
- : eventDispatcher(0)
- , maybeCancelWaitForMoreEvents(0)
- , enableNotifiersObserver(0)
-{
-
-}
-
-QCFSocketNotifier::~QCFSocketNotifier()
-{
-
-}
-
-void QCFSocketNotifier::setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher)
-{
- eventDispatcher = hostEventDispacher;
-}
-
-void QCFSocketNotifier::setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack)
-{
- maybeCancelWaitForMoreEvents = callBack;
-}
-
-void QCFSocketNotifier::registerSocketNotifier(QSocketNotifier *notifier)
-{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != eventDispatcher->thread()
- || eventDispatcher->thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
- return;
- }
-#endif
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on iOS");
- return;
- }
-
- // Check if we have a CFSocket for the native socket, create one if not.
- MacSocketInfo *socketInfo = macSockets.value(nativeSocket);
- if (!socketInfo) {
- socketInfo = new MacSocketInfo();
-
- // Create CFSocket, specify that we want both read and write callbacks (the callbacks
- // are enabled/disabled later on).
- const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
- CFSocketContext context = {0, this, 0, 0, 0};
- socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
- if (CFSocketIsValid(socketInfo->socket) == false) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
- return;
- }
-
- CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
- // QSocketNotifier doesn't close the socket upon destruction/invalidation
- flags &= ~kCFSocketCloseOnInvalidate;
- // Expicitly disable automatic re-enable, as we do that manually on each runloop pass
- flags &= ~(kCFSocketAutomaticallyReenableWriteCallBack | kCFSocketAutomaticallyReenableReadCallBack);
- CFSocketSetSocketFlags(socketInfo->socket, flags);
-
- macSockets.insert(nativeSocket, socketInfo);
- }
-
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(socketInfo->readNotifier == 0);
- socketInfo->readNotifier = notifier;
- socketInfo->readEnabled = false;
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(socketInfo->writeNotifier == 0);
- socketInfo->writeNotifier = notifier;
- socketInfo->writeEnabled = false;
- }
-
- if (!enableNotifiersObserver) {
- // Create a run loop observer which enables the socket notifiers on each
- // pass of the run loop, before any sources are processed.
- CFRunLoopObserverContext context = {};
- context.info = this;
- enableNotifiersObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeSources,
- true, 0, enableSocketNotifiers, &context);
- Q_ASSERT(enableNotifiersObserver);
- CFRunLoopAddObserver(CFRunLoopGetMain(), enableNotifiersObserver, kCFRunLoopCommonModes);
- }
-}
-
-void QCFSocketNotifier::unregisterSocketNotifier(QSocketNotifier *notifier)
-{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != eventDispatcher->thread() || eventDispatcher->thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
- return;
- }
-#endif
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on iOS");
- return;
- }
- MacSocketInfo *socketInfo = macSockets.value(nativeSocket);
- if (!socketInfo) {
- qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier");
- return;
- }
-
- // Decrement read/write counters and disable callbacks if necessary.
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(notifier == socketInfo->readNotifier);
- socketInfo->readNotifier = 0;
- socketInfo->readEnabled = false;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(notifier == socketInfo->writeNotifier);
- socketInfo->writeNotifier = 0;
- socketInfo->writeEnabled = false;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
-
- // Remove CFSocket from runloop if this was the last QSocketNotifier.
- if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) {
- unregisterSocketInfo(socketInfo);
- delete socketInfo;
- macSockets.remove(nativeSocket);
- }
-}
-
-void QCFSocketNotifier::removeSocketNotifiers()
-{
- // Remove CFSockets from the runloop.
- foreach (MacSocketInfo *socketInfo, macSockets) {
- unregisterSocketInfo(socketInfo);
- delete socketInfo;
- }
-
- macSockets.clear();
-
- destroyRunLoopObserver();
-}
-
-void QCFSocketNotifier::destroyRunLoopObserver()
-{
- if (!enableNotifiersObserver)
- return;
-
- CFRunLoopObserverInvalidate(enableNotifiersObserver);
- CFRelease(enableNotifiersObserver);
- enableNotifiersObserver = 0;
-}
-
-void QCFSocketNotifier::unregisterSocketInfo(MacSocketInfo *socketInfo)
-{
- if (socketInfo->runloop) {
- if (CFSocketIsValid(socketInfo->socket))
- qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
- CFRunLoopSourceInvalidate(socketInfo->runloop);
- CFRelease(socketInfo->runloop);
- }
- CFSocketInvalidate(socketInfo->socket);
- CFRelease(socketInfo->socket);
-}
-
-void QCFSocketNotifier::enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info)
-{
- Q_UNUSED(ref);
- Q_UNUSED(activity);
-
- QCFSocketNotifier *that = static_cast<QCFSocketNotifier *>(info);
-
- foreach (MacSocketInfo *socketInfo, that->macSockets) {
- if (!CFSocketIsValid(socketInfo->socket))
- continue;
-
- if (!socketInfo->runloop) {
- // Add CFSocket to runloop.
- if (!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
- CFSocketInvalidate(socketInfo->socket);
- continue;
- }
-
- if (!socketInfo->readNotifier)
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- if (!socketInfo->writeNotifier)
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
-
- if (socketInfo->readNotifier && !socketInfo->readEnabled) {
- socketInfo->readEnabled = true;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- }
- if (socketInfo->writeNotifier && !socketInfo->writeEnabled) {
- socketInfo->writeEnabled = true;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
- }
-}
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h
deleted file mode 100644
index 9bccc1bf98..0000000000
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCFSOCKETNOTIFIER_P_H
-#define QCFSOCKETNOTIFIER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/qhash.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-struct MacSocketInfo {
- MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0),
- readEnabled(false), writeEnabled(false) {}
- CFSocketRef socket;
- CFRunLoopSourceRef runloop;
- QObject *readNotifier;
- QObject *writeNotifier;
- bool readEnabled;
- bool writeEnabled;
-};
-typedef QHash<int, MacSocketInfo *> MacSocketHash;
-
-typedef void (*MaybeCancelWaitForMoreEventsFn)(QAbstractEventDispatcher *hostEventDispacher);
-
-// The CoreFoundationSocketNotifier class implements socket notifiers support using
-// CFSocket for event dispatchers running on top of the Core Foundation run loop system.
-// (currently Mac and iOS)
-//
-// The principal functions are registerSocketNotifier() and unregisterSocketNotifier().
-//
-// setHostEventDispatcher() should be called at startup.
-// removeSocketNotifiers() should be called at shutdown.
-//
-class QCFSocketNotifier
-{
-public:
- QCFSocketNotifier();
- ~QCFSocketNotifier();
- void setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher);
- void setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack);
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
- void removeSocketNotifiers();
-
-private:
- void destroyRunLoopObserver();
-
- static void unregisterSocketInfo(MacSocketInfo *socketInfo);
- static void enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
-
- MacSocketHash macSockets;
- QAbstractEventDispatcher *eventDispatcher;
- MaybeCancelWaitForMoreEventsFn maybeCancelWaitForMoreEvents;
- CFRunLoopObserverRef enableNotifiersObserver;
-
- friend void qt_mac_socket_callback(CFSocketRef, CFSocketCallBackType, CFDataRef, const void *, void *);
-};
-
-QT_END_NAMESPACE
-
-#endif