From 3f9a2ce751c10acbea505bb18a60cb4cb0fbcef9 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 22 Nov 2012 10:50:59 +0100 Subject: BlackBerry: Restore proper BPS channel in event dispatcher This change ensures that BPS events are delivered to the proper channel even if the application code would change the channel. Backport from qtbase: 131b86347384a97a7044942acd723c4ef5669636 Change-Id: Ib2bdd3d973bc51f5ce85eb6ef9adcb3e57093a54 Reviewed-by: Fabian Bumberger Reviewed-by: Kevin Krammer Reviewed-by: Thomas McGuire --- src/corelib/kernel/qeventdispatcher_blackberry.cpp | 44 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp index 784e971..0a8b0a6 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp +++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp @@ -55,7 +55,29 @@ #define qEventDispatcherDebug QT_NO_QDEBUG_MACRO() #endif -struct bpsIOHandlerData { +class BpsChannelScopeSwitcher +{ +public: + BpsChannelScopeSwitcher(int scopeChannel) : innerChannel(scopeChannel) + { + outerChannel = bps_channel_get_active(); + if (outerChannel != innerChannel) + bps_channel_set_active(innerChannel); + } + + ~BpsChannelScopeSwitcher() + { + if (outerChannel != innerChannel) + bps_channel_set_active(outerChannel); + } + +private: + int innerChannel; + int outerChannel; +}; + +struct bpsIOHandlerData +{ bpsIOHandlerData() : count(0), readfds(0), writefds(0), exceptfds(0) { @@ -101,7 +123,7 @@ static int bpsIOHandler(int fd, int io_events, void *data) // but this only needs to happen once if multiple files become ready at the same time if (firstReady) { qEventDispatcherDebug << "Sending bpsIOReadyDomain event"; - // create IO ready event + // create unblock event bps_event_t *event; int result = bps_event_create(&event, bpsUnblockDomain, 0, NULL, NULL); if (result != BPS_SUCCESS) { @@ -109,7 +131,8 @@ static int bpsIOHandler(int fd, int io_events, void *data) return BPS_FAILURE; } - // post unblock event to our thread + // post unblock event to our thread; in this callback the bps channel is + // guarenteed to be the same that was active when bps_add_fd was called result = bps_push_event(event); if (result != BPS_SUCCESS) { qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_push_event() failed"); @@ -175,6 +198,9 @@ QEventDispatcherBlackberry::~QEventDispatcherBlackberry() void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); + Q_D(QEventDispatcherBlackberry); + + BpsChannelScopeSwitcher channelSwitcher(d->bps_channel); // Register the fd with bps int sockfd = notifier->socket(); @@ -205,8 +231,6 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie break; } - Q_D(QEventDispatcherBlackberry); - errno = 0; int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data()); @@ -216,6 +240,10 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier) { + Q_D(QEventDispatcherBlackberry); + + BpsChannelScopeSwitcher channelSwitcher(d->bps_channel); + // Allow the base Unix implementation to unregister the fd too QEventDispatcherUNIX::unregisterSocketNotifier(notifier); @@ -236,8 +264,6 @@ void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notif if (!io_events) return; - Q_D(QEventDispatcherBlackberry); - errno = 0; result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data()); if (result != BPS_SUCCESS) { @@ -249,12 +275,14 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef timeval *timeout) { Q_UNUSED(nfds); + Q_D(QEventDispatcherBlackberry); + + BpsChannelScopeSwitcher channelSwitcher(d->bps_channel); // Make a note of the start time timeval startTime = qt_gettime(); // prepare file sets for bps callback - Q_D(QEventDispatcherBlackberry); d->ioData->count = 0; d->ioData->readfds = readfds; d->ioData->writefds = writefds; -- cgit v0.12