diff options
author | Rafael Roquetto <rafael.roquetto.qnx@kdab.com> | 2012-06-28 12:16:46 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-07-05 10:16:20 (GMT) |
commit | fc90624f4651913c7dd0fa52db9b126d7e08f6b0 (patch) | |
tree | 1308886f7b763bcab6ba1250663ced5b472513e8 /src | |
parent | e2d853299cf383cdfbb6aa25aadd4e34a0a3cdca (diff) | |
download | Qt-fc90624f4651913c7dd0fa52db9b126d7e08f6b0.zip Qt-fc90624f4651913c7dd0fa52db9b126d7e08f6b0.tar.gz Qt-fc90624f4651913c7dd0fa52db9b126d7e08f6b0.tar.bz2 |
Fix socket notifier registration on Blackberry.
This fixes a bug on QEventDispatcherBlackberry, where registerSocketNotifier()
and unregisterSocketNotifier() wrongly assumed that a file descriptor was
being watched exclusively by one QSocketNotifier, while in fact there can be
more than one QSocketNotifier associated with a single file descriptor.
cherry-picked from qt5/qtbase: c10bc4c37d07dd7a9180d1810a379e370608c574.
Change-Id: Iad2de22f54038e101de744a91be56db00891aca1
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_blackberry.cpp | 59 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_blackberry_p.h | 1 |
2 files changed, 52 insertions, 8 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp index 5593e5e..1157098 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp +++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp @@ -158,14 +158,18 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie { Q_ASSERT(notifier); - // Call the base Unix implementation. Needed to allow select() to be called correctly - QEventDispatcherUNIX::registerSocketNotifier(notifier); - // Register the fd with bps int sockfd = notifier->socket(); int type = notifier->type(); - int io_events = 0; + int io_events = ioEvents(sockfd); + + if (io_events) + bps_remove_fd(sockfd); + + // Call the base Unix implementation. Needed to allow select() to be called correctly + QEventDispatcherUNIX::registerSocketNotifier(notifier); + switch (type) { case QSocketNotifier::Read: io_events |= BPS_IO_INPUT; @@ -180,21 +184,42 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie } Q_D(QEventDispatcherBlackberry); + + errno = 0; int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data()); + if (result != BPS_SUCCESS) - qWarning() << Q_FUNC_INFO << "bps_add_fd() failed"; + qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno; } void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier) { + // Allow the base Unix implementation to unregister the fd too + QEventDispatcherUNIX::unregisterSocketNotifier(notifier); + // Unregister the fd with bps int sockfd = notifier->socket(); + + const int io_events = ioEvents(sockfd); + int result = bps_remove_fd(sockfd); if (result != BPS_SUCCESS) - qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed"; + qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed" << sockfd; - // Allow the base Unix implementation to unregister the fd too - QEventDispatcherUNIX::unregisterSocketNotifier(notifier); + + /* if no other socket notifier is + * watching sockfd, our job ends here + */ + if (!io_events) + return; + + Q_D(QEventDispatcherBlackberry); + + errno = 0; + result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data()); + if (result != BPS_SUCCESS) { + qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno; + } } int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, @@ -259,4 +284,22 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef return d->ioData->count; } +int QEventDispatcherBlackberry::ioEvents(int fd) +{ + int io_events = 0; + + Q_D(QEventDispatcherBlackberry); + + if (FD_ISSET(fd, &d->sn_vec[0].enabled_fds)) + io_events |= BPS_IO_INPUT; + + if (FD_ISSET(fd, &d->sn_vec[1].enabled_fds)) + io_events |= BPS_IO_OUTPUT; + + if (FD_ISSET(fd, &d->sn_vec[2].enabled_fds)) + io_events |= BPS_IO_EXCEPT; + + return io_events; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h index 992de9d..1d31f27 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h +++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h @@ -76,6 +76,7 @@ protected: int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout); + int ioEvents(int fd); }; struct bpsIOHandlerData; |