/*!
    \example network/blockingfortuneclient
    \title Blocking Fortune Client Example

    The Blocking Fortune Client example shows how to create a client for a
    network service using QTcpSocket's synchronous API in a non-GUI thread.

    \image blockingfortuneclient-example.png

    QTcpSocket supports two general approaches to network programming:

    \list

    \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
    and performed when control returns to Qt's event loop. When the operation
    is finished, QTcpSocket emits a signal. For example,
    QTcpSocket::connectToHost() returns immediately, and when the connection
    has been established, QTcpSocket emits
    \l{QTcpSocket::connected()}{connected()}.
    
    \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
    applications, you can call the \c waitFor...() functions (e.g.,
    QTcpSocket::waitForConnected()) to suspend the calling thread until the
    operation has completed, instead of connecting to signals.

    \endlist

    The implementation is very similar to the
    \l{network/fortuneclient}{Fortune Client} example, but instead of having
    QTcpSocket as a member of the main class, doing asynchronous networking in
    the main thread, we will do all network operations in a separate thread
    and use QTcpSocket's blocking API.

    The purpose of this example is to demonstrate a pattern that you can use
    to simplify your networking code, without losing responsiveness in your
    user interface.  Use of Qt's blocking network API often leads to
    simpler code, but because of its blocking behavior, it should only be used
    in non-GUI threads to prevent the user interface from freezing. But
    contrary to what many think, using threads with QThread does not
    necessarily add unmanagable complexity to your application.

    We will start with the FortuneThread class, which handles the network
    code.

    \quotefromfile network/blockingfortuneclient/fortunethread.h
    \skipto class FortuneThread
    \printuntil };

    FortuneThread is a QThread subclass that provides an API for scheduling
    requests for fortunes, and it has signals for delivering fortunes and
    reporting errors. You can call requestNewFortune() to request a new
    fortune, and the result is delivered by the newFortune() signal. If any
    error occurs, the error() signal is emitted.

    It's important to notice that requestNewFortune() is called from the main,
    GUI thread, but the host name and port values it stores will be accessed
    from FortuneThread's thread. Because we will be reading and writing
    FortuneThread's data members from different threads concurrently, we use
    QMutex to synchronize access.

    \quotefromfile network/blockingfortuneclient/fortunethread.cpp
    \skipto requestNewFortune(
    \printuntil }

    The requestNewFortune() function stores the host name and port of the
    fortune server as member data, and we lock the mutex with QMutexLocker to
    protect this data. We then start the thread, unless it is already
    running. We will come back to the QWaitCondition::wakeOne() call later.

    \skipto run()
    \printuntil ;
    \printuntil mutex.unlock

    In the run() function, we start by acquiring the mutex lock, fetching the
    host name and port from the member data, and then releasing the lock
    again. The case that we are protecting ourselves against is that \c
    requestNewFortune() could be called at the same time as we are fetching
    this data. QString is \l reentrant but \e not \l{thread safe}, and we must
    also avoid the unlikely risk of reading the host name from one request,
    and port of another. And as you might have guessed, FortuneThread can only
    handle one request at a time.

    The run() function now enters a loop:

    \skipto while
    \printuntil socket.connectToHost

    The loop will continue requesting fortunes for as long as \e quit is
    false. We start our first request by creating a QTcpSocket on the stack,
    and then we call \l{QTcpSocket::connectToHost()}{connectToHost()}. This
    starts an asynchronous operation which, after control returns to Qt's
    event loop, will cause QTcpSocket to emit
    \l{QTcpSocket::connected()}{connected()} or
    \l{QTcpSocket::error()}{error()}.

    \printuntil }

    But since we are running in a non-GUI thread, we do not have to worry
    about blocking the user interface. So instead of entering an event loop,
    we simply call QTcpSocket::waitForConnected(). This function will wait,
    blocking the calling thread, until QTcpSocket emits connected() or an
    error occurs. If connected() is emitted, the function returns true; if the
    connection failed or timed out (which in this example happens after 5
    seconds), false is returned. QTcpSocket::waitForConnected(), like the
    other \c waitFor...() functions, is part of QTcpSocket's \e{blocking
    API}.

    After this statement, we have a connected socket to work with. Now it's
    time to see what the fortune server has sent us.

    \printuntil }        
    \printuntil }

    This step is to read the size of the packet. Although we are only reading
    two bytes here, and the \c while loop may seem to overdo it, we present this
    code to demonstrate a good pattern for waiting for data using
    QTcpSocket::waitForReadyRead(). It goes like this: For as long as we still
    need more data, we call waitForReadyRead(). If it returns false,
    we abort the operation. After this statement, we know that we have received
    enough data.

    \printuntil in >>

    Now we can create a QDataStream object, passing the socket to
    QDataStream's constructor, and as in the other client examples we set
    the stream protocol version to QDataStream::Qt_4_0, and read the size
    of the packet.

    \printuntil }
    \printuntil }

    Again, we'll use a loop that waits for more data by calling
    QTcpSocket::waitForReadyRead(). In this loop, we're waiting until
    QTcpSocket::bytesAvailable() returns the full packet size.

    \printuntil emit

    Now that we have all the data that we need, we can use QDataStream to
    read the fortune string from the packet. The resulting fortune is
    delivered by emitting newFortune().

    \printuntil }

    The final part of our loop is that we acquire the mutex so that we can
    safely read from our member data. We then let the thread go to sleep by
    calling QWaitCondition::wait(). At this point, we can go back to
    requestNewFortune() and look closed at the call to wakeOne():

    \quotefromfile network/blockingfortuneclient/fortunethread.cpp
    \skipto requestNewFortune
    \printuntil {
    \dots
    \skipto if
    \printuntil /^\}$/

    What happened here was that because the thread falls asleep waiting for a
    new request, we needed to wake it up again when a new request
    arrives. QWaitCondition is often used in threads to signal a wakeup call
    like this.

    \quotefromfile network/blockingfortuneclient/fortunethread.cpp
    \skipto ~Fortune
    \printuntil }

    Finishing off the FortuneThread walkthrough, this is the destructor that
    sets \e quit to true, wakes up the thread and waits for the thread to exit
    before returning. This lets the \c while loop in run() will finish its current
    iteration. When run() returns, the thread will terminate and be destroyed.

    Now for the BlockingClient class:

    \quotefromfile network/blockingfortuneclient/blockingclient.h
    \skipto class BlockingClient
    \printuntil };

    BlockingClient is very similar to the Client class in the
    \l{network/fortuneclient}{Fortune Client} example, but in this class
    we store a FortuneThread member instead of a pointer to a QTcpSocket.
    When the user clicks the "Get Fortune" button, the same slot is called,
    but its implementation is slightly different:

    \quotefromfile network/blockingfortuneclient/blockingclient.cpp
    \skipto connect(&thread
    \printuntil ;
    \printuntil ;

    We connect our FortuneThread's two signals newFortune() and error() (which
    are somewhat similar to QTcpSocket::readyRead() and QTcpSocket::error() in
    the previous example) to requestNewFortune() and displayError().

    \quotefromfile network/blockingfortuneclient/blockingclient.cpp
    \skipto ::requestNewFortune()
    \printuntil }

    The requestNewFortune() slot calls FortuneThread::requestNewFortune(),
    which \e shedules the request. When the thread has received a new fortune
    and emits newFortune(), our showFortune() slot is called:

    \skipto showFortune(
    \printuntil }
    \printuntil }
    
    Here, we simply display the fortune we received as the argument.

    \sa {Fortune Client Example}, {Fortune Server Example}
*/
