×

Discussion Board

Results 1 to 2 of 2
  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    22

    Question Blocking I/O on QBluetoothSocket

    Is there an easy way to do blocking I/O on a QBluetoothSocket?

    What I would like to have is something as simple as this:

    socket->write(data);
    socket->waitForReadyRead(-1); // Wait even if it blocks the UI thread, I don't care.
    socket->read(..);

    However, I seems things are not that straightforward.
    * The waitForReadyRead method of QBluetoothSocket does not really implement any waiting and responds immediately with false, it is just the inherited QIODevice::waitForReadyRead.

    * The next "natural" idea is the following:

    socket->write(data);
    int loops = 1000000;
    while(!socket->bytesAvailable() && loops--) ;
    socket->read(...)

    Unfortunately it does not work. Basically it blocks the program but the socket won't do any receiving during the loop either, and by the end of the loop it still has bytesAvailable = 0.

    * I tried to use an advice found somewhere on the net to expose QThread::msleep and call that to do the waiting. Unfortunately, this simply crashes my application (a QML app@N950).

    * Next I tried using the SequentialAnimation trick:
    SequentialAnimation {
    ScriptAction { writeData(); }
    PauseAnimation { interval: 100; } // I am sure I will get my response within this time.
    ScriptAction { readData(); }
    }
    This actually does work in the sense that readData() gets some data back, however, for reasons beyond my understanding, at that point the socket->read() function responds with *more* data than the server has actually sent. The returned array has the proper response in the beginning but is filled with random garbage to the end. And in any case this does more waiting that I would like to do.

    * In the end, it seems that the only place where socket->read() works as needed is the onReadyRead slot, hence waiting for this should be the only right thing to do. But how?

    Having seen other discussions in the net regarding this topic I must mention that yes, I know of some weird ways to overcome this limitation by only working with signals and slots, such as pushing protocol commands into a self-made queue, which manages the sending and listening to responses. However, it is cumbersome and rather limiting. In particular, it does not allow to do a simple "remote function call" over bluetooth, which is what I need here. It can't be the case that it is impossible to have a simple waitForReadyRead on a QBluetoothSocket. Or is it?

  2. #2
    Registered User
    Join Date
    Sep 2011
    Posts
    22

    Re: Blocking I/O on QBluetoothSocket

    OK, after a couple of sleepless nights trying out all possible ways of running QBluetoothSocket in a separate thread and waiting for results in the main thread I came to the conclusion that with current QtMobility this is most probably impossible and the only reasonable solution to my problem is to simply
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/rfcomm.h>
    and go on working with the standard Berkeley socket connect/send/recv operations, making sure the O_NONBLOCK flag is not set.

    Now as for QtMobility, I think there are a couple of places which are worth fixing. I realy hope some of the developers would be reading this. (I'm very new to the whole Qt thing and am not sure which is the right channel for reporting issues. Someone direct me to a better place, if you believe the issues below are worth reporting).

    * Issue number one: obviously there is a need for "waitForReadyRead" implementation. It should be fairly easy to do on the level of QBluetoothSocketPrivate but is close to impossible anywhere else, where the access to the low-level socket handle is not availalble.
    * Issue number two: why not let the user choose between a blocking and a nonblocking implementation? Again, this seems trivial "from the inside" (just flipping a single flag on the socket descriptor).
    * Issue number three, the one which probably cost me a sleepless night:

    Somewhere inside qbluetoothsocket_bluez.cpp there is a line like that:
    readNotifier = new QSocketNotifier(socket, QSocketNotifier::Read);
    As far as I can understand, this line creates a readNotifier object. Moreover, as no parent is given, it is created in the current thread (i.e. the "main" thread). Consequently, any attempts to push QBluetoothSocket onto a parallel thread and put the main thread into waiting state until the socket does its job fail because the socket relies on the readNotifier event handling, and this handling will always be bound to the main thread, no matter where you move the QBluetoothSocket's event processing.

    To make things worse, right nearby there is a line like that:
    connectWriteNotifier = new QSocketNotifier(socket, QSocketNotifier::Write, q);
    which creates a write/connect notifier object, and assigns it to be the child of QBluetoothSocket, hence all connect and write notifications do get processed in the same thread with QBluetoothSocket.

    For the API user like me this means the following experience:
    * Thought: Let's do a socket->connectToService() and then sleep() until socket->state() changes.
    * ... test and observe things do not work ..
    * Thought: Ah, of course, perhaps QBluetoothSocket needs a separate thread to handle its notification/state changing logic.
    * ... write the following code:
    thread = new QThread();
    thread->start();
    socket->moveToThread(thread);
    * ... observe that now connection does work as expected, i.e. if we just call socket->connect() and sleep() the main thread until socket->state() changes,
    then this does happen at some point and the socket is connected.
    * Thought: Jippii, cracked it. Now let's just use the same trick for sending/receiving data.
    * ... fail miserably.
    * ... spend the night trying to understand what's happening, testing out various hypotheses, always failing.
    * ... finally dig into QBluetoothSocket's sources and figure out the problem. Get disappointed. Get a drink.

Similar Threads

  1. recv blocking for non-blocking socket
    By ACSS in forum Open C/C++
    Replies: 2
    Last Post: 2009-06-02, 09:51
  2. Blocking the Handset
    By srijai in forum Mobile Java General
    Replies: 2
    Last Post: 2007-07-18, 20:16
  3. Web blocking
    By Svat_ in forum Symbian
    Replies: 2
    Last Post: 2006-11-13, 11:44
  4. Regarding Web blocking
    By Svat_ in forum Symbian Networking & Messaging (Closed)
    Replies: 0
    Last Post: 2006-11-13, 10:14
  5. I/O blocking
    By ykaliuta in forum Mobile Java General
    Replies: 0
    Last Post: 2003-02-27, 06:29

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×