Question

I am developing a networking-based app for the blackberry playbook using Qt4.8.3, part of which involves storing a QAbstractSocket in a QScopedPointer as follows:

QScopedPointer<QAbstractSocket> nntp;

In my implementation, I store either a QSslSocket or a QTcpSocket (both of which inherit from QAbstractSocket) depending on whether the conenction is to be encrypted, i.e.,

if(ssl) {
    nntp.reset(new QSslSocket(this));
    (dynamic_cast<QSslSocket*>(nntp.data())))->connectToHostEncrypted(server, port);
} else {
    nntp.reset(new QTcpSocket(this));
    nntp->connectToHost(server, port);
}

When going down the ssl route (non-ssl works fine!), I end up with the following run time error:

virtual void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier*) bps_remove_fd() failed 19

The error is probably blackberry related given the error description and the fact that the code works as expected on other platforms (tested on mac and linux). (Note, the number 19 refers to the file descriptor).

Any ideas why I am seeing this error and how I can fix it?

Thanks,

Ben.

EDIT: I've just realised that instead of using the pointer, I can just have a single QSslSocket and treat it as a regular QTcpSocket when in non-ssl mode. Far easier. I would still like to know the reason for the above error however

Was it helpful?

Solution

We can have a look at the source code in order to see what is happening. The source code of unregisterSocketNotifier is:

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);
}

And do a correlation with bps_remove_fd documentation which says:

If the file descriptor is present it is removed from the channel. The io_handler callback and associated user data are also removed.

[returns] BPS_SUCCESS if the fd (file descriptor) was successfully removed from the channel, BPS_FAILURE with errno value set otherwise.

The only clues about what could make bps_remove_fd fail are the possibility that fd is not present, which would mean that your socket does not have any valid file descriptor. The other error could be that for whichever reason not specified, the file exists but is not removed.

The variable errno should be set, so you may have a more complete error description if you look at it - I did not try though, I don't have what it takes -.

I bet bps_remove_fd works on the same principle than POSIX's close(int fd), so I had a look at close's documentation to see what could cause a failure. It states that it shall/may fail in the following cases:

  • The argument is not a valid file descriptor (shall fail).
  • close may be interrupted by a signal (shall fail).
  • An I/O error occurred while reading from or writing to the file system (may fail).

I would have made this answer a comment since it does not really answer the question in your particular case, but I hope it may at least help you understand what's going on a little bit more :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top