diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2015-10-01 17:41:07 +0300 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@theqtcompany.com> | 2015-10-02 10:16:53 +0000 |
commit | b8e0f7cfc638a71770f44ada828ff2cf6d2ee201 (patch) | |
tree | 5da2fd9c3225ea35333686149c5263d1e579f61e /src/plugins | |
parent | 7943d4f77c721da17b6be76cf1045d34654a8cc5 (diff) |
Fix the spurious socket notifications on OS X
Core Foundation Framework forwards notifications about socket activity
through a callback function which called from the run loop. Previous
implementation sets kCFSocketReadCallBack, kCFSocketWriteCallBack to be
automatically re-enabled after they are triggered. With these semantics,
an application need not read all available data in response to a read
notification: a single recv in response to each read notification is
appropriate. If an application issues multiple recv calls in response to
a single notification, it can receive spurious notifications.
To solve this issue, this patch disables automatically reenabling callback
feature. Now, callback gets called exactly once, and is not called again
until manually re-enabled by calling CFSocketEnableCallBacks() just before
entering to wait for the new events.
Task-number: QTBUG-48556
Change-Id: Ia3393c2026230c7b3397cc614758dec1d432535f
Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 52b2e23345..b443233d15 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -845,10 +845,13 @@ QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity activity, void *info) { - if (activity == kCFRunLoopBeforeWaiting) - emit static_cast<QCocoaEventDispatcher*>(info)->aboutToBlock(); - else - emit static_cast<QCocoaEventDispatcher*>(info)->awake(); + QCocoaEventDispatcher *dispatcher = static_cast<QCocoaEventDispatcher *>(info); + if (activity == kCFRunLoopBeforeWaiting) { + dispatcher->d_func()->cfSocketNotifier.enableSocketNotifiers(); + emit dispatcher->aboutToBlock(); + } else { + emit dispatcher->awake(); + } } void QCocoaEventDispatcherPrivate::processPostedEvents() |