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. Change-Id: I0ce54bf809df109ad97f4a7f170f448d5d04d453 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
This commit is contained in:
parent
5c5eb92419
commit
c10bc4c37d
@ -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)
|
||||
{
|
||||
// Unregister the fd with bps
|
||||
int sockfd = notifier->socket();
|
||||
int result = bps_remove_fd(sockfd);
|
||||
if (result != BPS_SUCCESS)
|
||||
qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed";
|
||||
|
||||
// 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" << sockfd;
|
||||
|
||||
|
||||
/* 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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user