Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
34 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/network/socket/qabstractsocket.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949
    5050    \reentrant
    51     \ingroup io
     51    \ingroup network
    5252    \inmodule QtNetwork
    5353
     
    100100    write buffer size. You can monitor its size by listening to this
    101101    signal.
    102    
     102
    103103    The readyRead() signal is emitted every time a new chunk of data
    104104    has arrived. bytesAvailable() then returns the number of bytes
     
    161161    is available before attempting to read it using operator>>().
    162162
    163     \sa QFtp, QHttp, QTcpServer
     163    \sa QFtp, QNetworkAccessManager, QTcpServer
    164164*/
    165165
     
    200200
    201201    QAbstractSocket::SocketError is not a registered metatype, so for queued
    202     connections, you will have to register it with Q_REGISTER_METATYPE.
    203 
    204     \sa error(), errorString()
     202    connections, you will have to register it with Q_DECLARE_METATYPE() and
     203    qRegisterMetaType().
     204
     205    \sa error(), errorString(), {Creating Custom Qt Types}
    205206*/
    206207
     
    212213
    213214    QAbstractSocket::SocketState is not a registered metatype, so for queued
    214     connections, you will have to register it with Q_REGISTER_METATYPE.
    215 
    216     \sa state()
     215    connections, you will have to register it with Q_REGISTER_METATYPE() and
     216    qRegisterMetaType().
     217
     218    \sa state(), {Creating Custom Qt Types}
    217219*/
    218220
     
    331333*/
    332334
     335/*!
     336    \enum QAbstractSocket::SocketOption
     337    \since 4.6
     338
     339    This enum represents the options that can be set on a socket.
     340    If desired, they can be set after having received the connected() signal from
     341    the socket or after having received a new socket from a QTcpServer.
     342
     343    \value LowDelayOption Try to optimize the socket for low latency. For a QTcpSocket
     344    this would set the TCP_NODELAY option and disable Nagle's algorithm. Set this to 1
     345    to enable.
     346    \value KeepAliveOption Set this to 1 to enable the SO_KEEPALIVE socket option
     347
     348    \sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
     349*/
     350
    333351#include "qabstractsocket.h"
    334352#include "qabstractsocket_p.h"
     
    436454      socketEngine(0),
    437455      cachedSocketDescriptor(-1),
     456#ifdef Q_OS_LINUX
     457      addToBytesAvailable(0),
     458#endif
    438459      readBufferMaxSize(0),
    439460      readBuffer(QABSTRACTSOCKET_BUFFERSIZE),
     
    442463      blockingTimeout(30000),
    443464      connectTimer(0),
     465      disconnectTimer(0),
    444466      connectTimeElapsed(0),
    445467      hostLookupId(-1),
     468      socketType(QAbstractSocket::UnknownSocketType),
    446469      state(QAbstractSocket::UnconnectedState),
    447470      socketError(QAbstractSocket::UnknownSocketError)
     
    476499        cachedSocketDescriptor = -1;
    477500    }
    478     if (connectTimer) {
     501    if (connectTimer)
    479502        connectTimer->stop();
    480     }
     503    if (disconnectTimer)
     504        disconnectTimer->stop();
    481505}
    482506
     
    648672    if (socketEngine) {
    649673#if defined (Q_OS_WIN)
    650         if (!writeBuffer.isEmpty())
    651             socketEngine->setWriteNotificationEnabled(true);
     674        if (!writeBuffer.isEmpty())
     675            socketEngine->setWriteNotificationEnabled(true);
    652676#else
    653         if (writeBuffer.isEmpty())
    654             socketEngine->setWriteNotificationEnabled(false);
     677        if (writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0)
     678            socketEngine->setWriteNotificationEnabled(false);
    655679#endif
    656680    }
     
    689713{
    690714    Q_Q(QAbstractSocket);
    691     if (!socketEngine || !socketEngine->isValid() || writeBuffer.isEmpty()) {
     715    if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty()
     716        && socketEngine->bytesToWrite() == 0)) {
    692717#if defined (QABSTRACTSOCKET_DEBUG)
    693718    qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s",
    694719           socketEngine->isValid() ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no");
    695720#endif
     721
     722        // this covers the case when the buffer was empty, but we had to wait for the socket engine to finish
     723        if (state == QAbstractSocket::ClosingState)
     724            q->disconnectFromHost();
     725
    696726        return false;
    697727    }
     
    730760    }
    731761
    732     if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled())
     762    if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled()
     763        && !socketEngine->bytesToWrite())
    733764        socketEngine->setWriteNotificationEnabled(false);
    734765    if (state == QAbstractSocket::ClosingState)
     
    851882        s += addresses.at(i).toString();
    852883    }
    853     s += "}";
     884    s += '}';
    854885    qDebug("QAbstractSocketPrivate::_q_startConnecting(hostInfo == %s)", s.toLatin1().constData());
    855886#endif
     
    10521083    if (socketEngine)
    10531084        socketEngine->setWriteNotificationEnabled(false);
     1085
    10541086    connectTimer->stop();
    10551087
     
    10621094    } else {
    10631095        _q_connectToNextAddress();
     1096    }
     1097}
     1098
     1099void QAbstractSocketPrivate::_q_forceDisconnect()
     1100{
     1101    Q_Q(QAbstractSocket);
     1102    if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) {
     1103        socketEngine->close();
     1104        q->disconnectFromHost();
    10641105    }
    10651106}
     
    11281169/*! \internal
    11291170
    1130     Sets up the the internal state after the connection has succeeded.
     1171    Sets up the internal state after the connection has succeeded.
    11311172*/
    11321173void QAbstractSocketPrivate::fetchConnectionParameters()
     
    12321273    \a hostName may be an IP address in string form (e.g.,
    12331274    "43.195.83.32"), or it may be a host name (e.g.,
    1234     "qtsoftware.com"). QAbstractSocket will do a lookup only if
     1275    "example.com"). QAbstractSocket will do a lookup only if
    12351276    required. \a port is in native byte order.
    12361277
     
    12641305#endif
    12651306
    1266     if (d->state == ConnectedState || d->state == ConnectingState) {
    1267         qWarning("QAbstractSocket::connectToHost() called when already connecting/connected to \"%s\"", qPrintable(hostName));
     1307    if (d->state == ConnectedState || d->state == ConnectingState
     1308        || d->state == ClosingState || d->state == HostLookupState) {
     1309        qWarning("QAbstractSocket::connectToHost() called when already looking up or connecting/connected to \"%s\"", qPrintable(hostName));
    12681310        return;
    12691311    }
     
    15471589}
    15481590
     1591/*!
     1592    \since 4.6
     1593    Sets the given \a option to the value described by \a value.
     1594
     1595    \sa socketOption()
     1596*/
     1597void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
     1598{
     1599#ifndef QT_NO_OPENSSL
     1600    if (QSslSocket *sslSocket = qobject_cast<QSslSocket*>(this)) {
     1601        sslSocket->setSocketOption(option, value);
     1602        return;
     1603    }
     1604#endif
     1605
     1606    if (!d_func()->socketEngine)
     1607        return;
     1608
     1609    switch (option) {
     1610        case LowDelayOption:
     1611            d_func()->socketEngine->setOption(QAbstractSocketEngine::LowDelayOption, value.toInt());
     1612            break;
     1613
     1614        case KeepAliveOption:
     1615            d_func()->socketEngine->setOption(QAbstractSocketEngine::KeepAliveOption, value.toInt());
     1616            break;
     1617    }
     1618}
     1619
     1620/*!
     1621    \since 4.6
     1622    Returns the value of the \a option option.
     1623
     1624    \sa setSocketOption()
     1625*/
     1626QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option)
     1627{
     1628#ifndef QT_NO_OPENSSL
     1629    if (QSslSocket *sslSocket = qobject_cast<QSslSocket*>(this)) {
     1630        return sslSocket->socketOption(option);
     1631    }
     1632#endif
     1633
     1634    if (!d_func()->socketEngine)
     1635        return QVariant();
     1636
     1637    int ret = -1;
     1638    switch (option) {
     1639        case LowDelayOption:
     1640            ret = d_func()->socketEngine->option(QAbstractSocketEngine::LowDelayOption);
     1641            break;
     1642
     1643        case KeepAliveOption:
     1644            ret = d_func()->socketEngine->option(QAbstractSocketEngine::KeepAliveOption);
     1645            break;
     1646    }
     1647    if (ret == -1)
     1648        return QVariant();
     1649    else
     1650        return QVariant(ret);
     1651}
     1652
     1653
    15491654/*
    15501655   Returns the difference between msecs and elapsed. If msecs is -1,
     
    16571762
    16581763/*!
    1659     This function blocks until data is available for reading and the
     1764    This function blocks until new data is available for reading and the
    16601765    \l{QIODevice::}{readyRead()} signal has been emitted. The function
    16611766    will timeout after \a msecs milliseconds; the default timeout is
     
    16631768
    16641769    The function returns true if the readyRead() signal is emitted and
    1665     there is data available for reading; otherwise it returns false
     1770    there is new data available for reading; otherwise it returns false
    16661771    (if an error occurred or the operation timed out).
    16671772
     
    18651970
    18661971/*!
    1867     Aborts the current connection and resets the socket. Unlike
    1868     disconnectFromHost(), this function immediately closes the socket, discarding
    1869     any pending data in the write buffer.
     1972    Aborts the current connection and resets the socket. Unlike disconnectFromHost(),
     1973    this function immediately closes the socket, discarding any pending data in the
     1974    write buffer.
    18701975
    18711976    \sa disconnectFromHost(), close()
     
    21642269
    21652270/*!
    2166     Disconnects the socket's connection with the host.
     2271    Closes the I/O device for the socket, disconnects the socket's connection with the
     2272    host, closes the socket, and resets the name, address, port number and underlying
     2273    socket descriptor.
     2274
     2275    See QIODevice::close() for a description of the actions that occur when an I/O
     2276    device is closed.
    21672277
    21682278    \sa abort()
     
    22562366
    22572367        // Wait for pending data to be written.
    2258         if (d->socketEngine && d->socketEngine->isValid() && d->writeBuffer.size() > 0) {
     2368        if (d->socketEngine && d->socketEngine->isValid() && (d->writeBuffer.size() > 0
     2369            || d->socketEngine->bytesToWrite() > 0)) {
     2370            // hack: when we are waiting for the socket engine to write bytes (only
     2371            // possible when using Socks5 or HTTP socket engine), then close
     2372            // anyway after 2 seconds. This is to prevent a timeout on Mac, where we
     2373            // sometimes just did not get the write notifier from the underlying
     2374            // CFSocket and no progress was made.
     2375            if (d->writeBuffer.size() == 0 && d->socketEngine->bytesToWrite() > 0) {
     2376                if (!d->disconnectTimer) {
     2377                    d->disconnectTimer = new QTimer(this);
     2378                    connect(d->disconnectTimer, SIGNAL(timeout()), this,
     2379                            SLOT(_q_forceDisconnect()), Qt::DirectConnection);
     2380                }
     2381                if (!d->disconnectTimer->isActive())
     2382                    d->disconnectTimer->start(2000);
     2383            }
    22592384            d->socketEngine->setWriteNotificationEnabled(true);
    22602385
     
    24572582
    24582583#ifdef QT3_SUPPORT
    2459 /*! \enum QAbstractSocket::Error
     2584/*!
     2585    \enum QAbstractSocket::Error
    24602586    \compat
    24612587
     
    25892715        break;
    25902716    default:
    2591         debug << "QAbstractSocket::SocketError(" << int(error) << ")";
     2717        debug << "QAbstractSocket::SocketError(" << int(error) << ')';
    25922718        break;
    25932719    }
     
    26202746        break;
    26212747    default:
    2622         debug << "QAbstractSocket::SocketState(" << int(state) << ")";
     2748        debug << "QAbstractSocket::SocketState(" << int(state) << ')';
    26232749        break;
    26242750    }
  • trunk/src/network/socket/qabstractsocket.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    117117#endif
    118118    };
     119    enum SocketOption {
     120        LowDelayOption, // TCP_NODELAY
     121        KeepAliveOption // SO_KEEPALIVE
     122    };
    119123
    120124    QAbstractSocket(SocketType socketType, QObject *parent);
     
    149153    bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState,
    150154                             OpenMode openMode = ReadWrite);
     155
     156    // ### Qt 5: Make virtual?
     157    void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value);
     158    QVariant socketOption(QAbstractSocket::SocketOption option);
    151159
    152160    SocketType socketType() const;
     
    209217    Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt())
    210218    Q_PRIVATE_SLOT(d_func(), void _q_testConnection())
     219    Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
    211220
    212221#ifdef QT3_SUPPORT
  • trunk/src/network/socket/qabstractsocket_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848//
    4949// This file is not part of the Qt API.  It exists for the convenience
    50 // of the QLibrary class.  This header file may change from
     50// of the QAbstractSocket class.  This header file may change from
    5151// version to version without notice, or even be removed.
    5252//
     
    9494    void _q_testConnection();
    9595    void _q_abortConnectionAttempt();
     96    void _q_forceDisconnect();
    9697
    9798    bool readSocketNotifierCalled;
     
    149150
    150151    QTimer *connectTimer;
     152    QTimer *disconnectTimer;
    151153    int connectTimeElapsed;
    152154
  • trunk/src/network/socket/qabstractsocketengine.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/network/socket/qabstractsocketengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9393        AddressReusable,
    9494        BindExclusively,
    95         ReceiveOutOfBandData
     95        ReceiveOutOfBandData,
     96        LowDelayOption,
     97        KeepAliveOption
    9698    };
    9799
     
    124126    virtual qint64 pendingDatagramSize() const = 0;
    125127#endif
     128
     129    virtual qint64 bytesToWrite() const = 0;
    126130
    127131    virtual int option(SocketOption option) const = 0;
  • trunk/src/network/socket/qhttpsocketengine.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    277277#endif // QT_NO_UDPSOCKET
    278278
    279 int QHttpSocketEngine::option(SocketOption) const
    280 {
     279qint64 QHttpSocketEngine::bytesToWrite() const
     280{
     281    Q_D(const QHttpSocketEngine);
     282    if (d->socket) {
     283        return d->socket->bytesToWrite();
     284    } else {
     285        return 0;
     286    }
     287}
     288
     289int QHttpSocketEngine::option(SocketOption option) const
     290{
     291    Q_D(const QHttpSocketEngine);
     292    if (d->socket) {
     293        // convert the enum and call the real socket
     294        if (option == QAbstractSocketEngine::LowDelayOption)
     295            return d->socket->socketOption(QAbstractSocket::LowDelayOption).toInt();
     296        if (option == QAbstractSocketEngine::KeepAliveOption)
     297            return d->socket->socketOption(QAbstractSocket::KeepAliveOption).toInt();
     298    }
    281299    return -1;
    282300}
    283301
    284 bool QHttpSocketEngine::setOption(SocketOption, int)
    285 {
     302bool QHttpSocketEngine::setOption(SocketOption option, int value)
     303{
     304    Q_D(QHttpSocketEngine);
     305    if (d->socket) {
     306        // convert the enum and call the real socket
     307        if (option == QAbstractSocketEngine::LowDelayOption)
     308            d->socket->setSocketOption(QAbstractSocket::LowDelayOption, value);
     309        if (option == QAbstractSocketEngine::KeepAliveOption)
     310            d->socket->setSocketOption(QAbstractSocket::KeepAliveOption, value);
     311        return true;
     312    }
    286313    return false;
    287314}
     
    455482    data += " HTTP/1.1\r\n";
    456483    data += "Proxy-Connection: keep-alive\r\n"
     484            "User-Agent: Mozilla/5.0\r\n"
    457485            "Host: " + peerAddress + "\r\n";
    458486    QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
     
    735763    , writeNotificationPending(false)
    736764    , connectionNotificationPending(false)
     765    , pendingResponseData(0)
    737766{
    738767    socket = 0;
     
    769798}
    770799
     800QT_END_NAMESPACE
     801
    771802#endif
    772 
    773 QT_END_NAMESPACE
  • trunk/src/network/socket/qhttpsocketengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    110110    qint64 pendingDatagramSize() const;
    111111#endif // QT_NO_UDPSOCKET
     112
     113    qint64 bytesToWrite() const;
    112114
    113115    int option(SocketOption option) const;
  • trunk/src/network/socket/qlocalserver.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7878    to use it without one. In that case, you must use waitForNewConnection(),
    7979    which blocks until either a connection is available or a timeout expires.
    80 
    81     Note that this feature is not supported on Windows 9x.
    8280
    8381    \sa QLocalSocket, QTcpServer
     
    277275        return 0;
    278276    QLocalSocket *nextSocket = d->pendingConnections.dequeue();
     277#ifdef Q_OS_SYMBIAN
     278    if(!d->socketNotifier)
     279        return nextSocket;
     280#endif
     281#ifndef QT_LOCALSOCKET_TCP
     282    if (d->pendingConnections.size() <= d->maxPendingConnections)
    279283#ifndef Q_OS_WIN
    280     d->socketNotifier->setEnabled(d->pendingConnections.size()
    281                                    <= d->maxPendingConnections);
     284        d->socketNotifier->setEnabled(true);
     285#else
     286        d->connectionEventNotifier->setEnabled(true);
     287#endif
    282288#endif
    283289    return nextSocket;
  • trunk/src/network/socket/qlocalserver.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8787private:
    8888    Q_DISABLE_COPY(QLocalServer)
    89 #if defined(QT_LOCALSOCKET_TCP)
    9089    Q_PRIVATE_SLOT(d_func(), void _q_onNewConnection())
    91 #elif defined(Q_OS_WIN)
    92     Q_PRIVATE_SLOT(d_func(), void _q_openSocket(HANDLE handle))
    93     Q_PRIVATE_SLOT(d_func(), void _q_stoppedListening())
    94     Q_PRIVATE_SLOT(d_func(), void _q_setError(QAbstractSocket::SocketError error, const QString &errorString))
    95 #else
    96     Q_PRIVATE_SLOT(d_func(), void _q_socketActivated())
    97 #endif
    9890};
    9991
  • trunk/src/network/socket/qlocalserver_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6464#elif defined(Q_OS_WIN)
    6565#   include <qt_windows.h>
    66 #   include <qthread.h>
     66#   include <private/qwineventnotifier_p.h>
    6767#else
    6868#   include <private/qnativesocketengine_p.h>
     
    7272QT_BEGIN_NAMESPACE
    7373
    74 #if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
    75 
    76 /*!
    77     \internal
    78     QLocalServerThread exists because Windows does not have a
    79     way to provide notifications when there is a new connections to
    80     the server.
    81   */
    82 class QLocalServerThread : public QThread
    83 {
    84     Q_OBJECT
    85 
    86 Q_SIGNALS:
    87     void connected(HANDLE newSocket);
    88     void error(QAbstractSocket::SocketError error, const QString &errorString);
    89 
    90 public:
    91     QLocalServerThread(QObject *parent = 0);
    92     ~QLocalServerThread();
    93     void closeServer();
    94 
    95 public:
    96     QString setName(const QString &name);
    97     void run();
    98     void stop();
    99     bool makeHandle();
    100 
    101     HANDLE gotConnectionEvent;
    102     QQueue<HANDLE> pendingHandles;
    103     int maxPendingConnections;
    104 private:
    105     HANDLE stopEvent;
    106     QString fullServerName;
    107 };
    108 
    109 #endif
    110 
    11174class QLocalServerPrivate : public QObjectPrivate
    11275{
     
    11578public:
    11679    QLocalServerPrivate() :
    117 #if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
    118             inWaitingFunction(false),
    119 #elif !defined(QT_LOCALSOCKET_TCP)
     80#if !defined(QT_LOCALSOCKET_TCP) && !defined(Q_OS_WIN)
    12081            listenSocket(-1), socketNotifier(0),
    12182#endif
     
    12990    void closeServer();
    13091    void waitForNewConnection(int msec, bool *timedOut);
     92    void _q_onNewConnection();
    13193
    13294#if defined(QT_LOCALSOCKET_TCP)
    133     void _q_onNewConnection();
    13495
    13596    QTcpServer tcpServer;
    13697    QMap<quintptr, QTcpSocket*> socketMap;
    13798#elif defined(Q_OS_WIN)
    138     void _q_openSocket(HANDLE socket);
    139     void _q_stoppedListening();
    140     void _q_setError(QAbstractSocket::SocketError error, const QString &errorString);
     99    struct Listener {
     100        HANDLE handle;
     101        OVERLAPPED overlapped;
     102    };
    141103
    142     QLocalServerThread waitForConnection;
    143     bool inWaitingFunction;
     104    void setError(const QString &function);
     105    bool addListener();
     106
     107    QList<Listener> listeners;
     108    HANDLE eventHandle;
     109    QWinEventNotifier *connectionEventNotifier;
    144110#else
    145111    void setError(const QString &function);
    146     void _q_socketActivated();
    147112
    148113    int listenSocket;
  • trunk/src/network/socket/qlocalserver_tcp.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9393    if (pendingConnections.isEmpty())
    9494        tcpServer.waitForNewConnection(msec, timedOut);
    95     else
     95    else if (timedOut)
    9696        *timedOut = false;
    9797}
  • trunk/src/network/socket/qlocalserver_unix.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444#include "qlocalsocket.h"
    4545#include "qlocalsocket_p.h"
     46#include "qnet_unix_p.h"
    4647
    4748#ifndef QT_NO_LOCALSERVER
     
    5354#include <qdir.h>
    5455#include <qdatetime.h>
     56
     57#ifdef Q_OS_VXWORKS
     58#  include <selectLib.h>
     59#endif
    5560
    5661QT_BEGIN_NAMESPACE
     
    8994
    9095    // create the unix socket
    91     listenSocket = qSocket(PF_UNIX, SOCK_STREAM, 0);
     96    listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0);
    9297    if (-1 == listenSocket) {
    9398        setError(QLatin1String("QLocalServer::listen"));
     
    107112             fullServerName.toLatin1().size() + 1);
    108113
     114#ifdef Q_OS_SYMBIAN
     115    // In SYMBIAN OS it can currently happen that accept is called twice,
     116    // once from waitForNewConnection and once via QSocketNotfier activity
     117    //
     118    // As an workaround, we set the socket to non blocking so possible
     119    // subsequent call to accept will not block in any case
     120    //
     121    // This change can be removed once more generic fix to select thread
     122    // syncronization problem is implemented.
     123    int flags = fcntl(listenSocket, F_GETFL, 0);
     124    if (-1 == flags
     125        || -1 == (fcntl(listenSocket, F_SETFL, flags | O_NONBLOCK))) {
     126        setError(QLatin1String("QLocalServer::listen"));
     127        closeServer();
     128        return false;
     129    }
     130#endif
     131
    109132    // bind
    110     if(-1 == qBind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) {
     133    if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) {
    111134        setError(QLatin1String("QLocalServer::listen"));
    112135        // if address is in use already, just close the socket, but do not delete the file
     
    121144
    122145    // listen for connections
    123     if (-1 == qListen(listenSocket, 50)) {
     146    if (-1 == qt_safe_listen(listenSocket, 50)) {
    124147        setError(QLatin1String("QLocalServer::listen"));
    125148        closeServer();
     
    133156                                         QSocketNotifier::Read, q);
    134157    q->connect(socketNotifier, SIGNAL(activated(int)),
    135                q, SLOT(_q_socketActivated()));
     158               q, SLOT(_q_onNewConnection()));
    136159    socketNotifier->setEnabled(maxPendingConnections > 0);
    137160    return true;
     
    149172    listenSocket = -1;
    150173
    151     if (socketNotifier)
     174    if (socketNotifier) {
     175        socketNotifier->setEnabled(false); // Otherwise, closed socket is checked before deleter runs
    152176        socketNotifier->deleteLater();
    153     socketNotifier = 0;
     177        socketNotifier = 0;
     178    }
    154179
    155180    if (!fullServerName.isEmpty())
     
    163188    Accept the new socket.
    164189 */
    165 void QLocalServerPrivate::_q_socketActivated()
     190void QLocalServerPrivate::_q_onNewConnection()
    166191{
    167192    Q_Q(QLocalServer);
     
    171196    ::sockaddr_un addr;
    172197    QT_SOCKLEN_T length = sizeof(sockaddr_un);
    173     int connectedSocket = qAccept(listenSocket, (sockaddr *)&addr, &length);
     198    int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length);
    174199    if(-1 == connectedSocket) {
    175200        setError(QLatin1String("QLocalSocket::activated"));
     
    192217    timeout.tv_usec = (msec % 1000) * 1000;
    193218
    194     // timeout can not be 0 or else select will return an error.
    195     if (0 == msec)
    196         timeout.tv_usec = 1000;
    197 
    198219    int result = -1;
    199     // on Linux timeout will be updated by select, but _not_ on other systems.
    200     QTime timer;
    201     timer.start();
    202     while (pendingConnections.isEmpty() && (-1 == msec || timer.elapsed() < msec)) {
    203         result = ::select(listenSocket + 1, &readfds, 0, 0, &timeout);
    204         if (-1 == result && errno != EINTR) {
    205             setError(QLatin1String("QLocalServer::waitForNewConnection"));
    206             closeServer();
    207             break;
    208         }
    209         if (result > 0)
    210             _q_socketActivated();
    211     }
     220    result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout);
     221    if (-1 == result) {
     222        setError(QLatin1String("QLocalServer::waitForNewConnection"));
     223        closeServer();
     224    }
     225    if (result > 0)
     226        _q_onNewConnection();
    212227    if (timedOut)
    213228        *timedOut = (result == 0);
  • trunk/src/network/socket/qlocalserver_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545
    4646#include <qdebug.h>
    47 #include <qdatetime.h>
    48 #include <qcoreapplication.h>
    49 #include <QMetaType>
    5047
    5148// The buffer size need to be 0 otherwise data could be
     
    5451#define BUFSIZE 0
    5552
     53// ###: This should be a property. Should replace the insane 50 on unix as well.
     54#define SYSTEM_MAX_PENDING_SOCKETS 8
     55
    5656QT_BEGIN_NAMESPACE
    5757
    58 QLocalServerThread::QLocalServerThread(QObject *parent) : QThread(parent),
    59     maxPendingConnections(1)
    60 {
    61     stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    62     gotConnectionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    63 }
    64 
    65 QLocalServerThread::~QLocalServerThread()
    66 {
    67     stop();
    68     closeServer();
    69     CloseHandle(stopEvent);
    70     CloseHandle(gotConnectionEvent);
    71 }
    72 
    73 void QLocalServerThread::stop()
    74 {
    75     if (isRunning()) {
    76         SetEvent(stopEvent);
    77         wait();
    78         ResetEvent(stopEvent);
    79     }
    80 }
    81 
    82 void QLocalServerThread::closeServer()
    83 {
    84     while (!pendingHandles.isEmpty())
    85         CloseHandle(pendingHandles.dequeue());
    86 }
    87 
    88 QString QLocalServerThread::setName(const QString &name)
    89 {
    90     QString pipePath = QLatin1String("\\\\.\\pipe\\");
    91     if (name.startsWith(pipePath))
    92         fullServerName = name;
    93     else
    94         fullServerName = pipePath + name;
    95     for (int i = pendingHandles.count(); i < maxPendingConnections; ++i)
    96         if (!makeHandle())
    97             break;
    98     return fullServerName;
    99 }
    100 
    101 bool QLocalServerThread::makeHandle()
    102 {
    103     if (pendingHandles.count() >= maxPendingConnections)
    104         return false;
    105 
    106     HANDLE handle = INVALID_HANDLE_VALUE;
    107     QT_WA({
    108     handle = CreateNamedPipeW(
    109                  (TCHAR*)fullServerName.utf16(), // pipe name
     58bool QLocalServerPrivate::addListener()
     59{
     60    // The object must not change its address once the
     61    // contained OVERLAPPED struct is passed to Windows.
     62    listeners << Listener();
     63    Listener &listener = listeners.last();
     64
     65    listener.handle = CreateNamedPipe(
     66                 (const wchar_t *)fullServerName.utf16(), // pipe name
    11067                 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,       // read/write access
    11168                 PIPE_TYPE_MESSAGE |       // message type pipe
     
    11774                 3000,                     // client time-out
    11875                 NULL);
    119     }, {
    120     handle = CreateNamedPipeA(
    121                  fullServerName.toLocal8Bit().constData(), // pipe name
    122                  PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,       // read/write access
    123                  PIPE_TYPE_MESSAGE |       // message type pipe
    124                  PIPE_READMODE_MESSAGE |   // message-read mode
    125                  PIPE_WAIT,                // blocking mode
    126                  PIPE_UNLIMITED_INSTANCES, // max. instances
    127                  BUFSIZE,                  // output buffer size
    128                  BUFSIZE,                  // input buffer size
    129                  3000,                     // client time-out
    130                  NULL);
    131     });
    132 
    133     if (INVALID_HANDLE_VALUE == handle) {
     76
     77    if (listener.handle == INVALID_HANDLE_VALUE) {
     78        setError(QLatin1String("QLocalServerPrivate::addListener"));
     79        listeners.removeLast();
    13480        return false;
    13581    }
    136     pendingHandles.enqueue(handle);
     82
     83    memset(&listener.overlapped, 0, sizeof(listener.overlapped));
     84    listener.overlapped.hEvent = eventHandle;
     85    if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) {
     86        switch (GetLastError()) {
     87        case ERROR_IO_PENDING:
     88            break;
     89        case ERROR_PIPE_CONNECTED:
     90            SetEvent(eventHandle);
     91            break;
     92        default:
     93            CloseHandle(listener.handle);
     94            setError(QLatin1String("QLocalServerPrivate::addListener"));
     95            listeners.removeLast();
     96            return false;
     97        }
     98    } else {
     99        Q_ASSERT_X(false, "QLocalServerPrivate::addListener", "The impossible happened");
     100        SetEvent(eventHandle);
     101    }
    137102    return true;
    138103}
    139104
    140 void QLocalServerThread::run()
    141 {
    142     OVERLAPPED  op;
    143     HANDLE      handleArray[2];
    144     memset(&op, 0, sizeof(op));
    145     handleArray[0] = op.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    146     handleArray[1] = stopEvent;
    147     HANDLE handle = INVALID_HANDLE_VALUE;
    148 
    149     forever {
    150         if (INVALID_HANDLE_VALUE == handle) {
    151             makeHandle();
    152             if (!pendingHandles.isEmpty())
    153                 handle = pendingHandles.dequeue();
    154         }
    155         if (INVALID_HANDLE_VALUE == handle) {
    156             int windowsError = GetLastError();
    157             QString function = QLatin1String("QLocalServer::run");
    158             QString errorString = QLocalServer::tr("%1: Unknown error %2").arg(function).arg(windowsError);
    159             emit error(QAbstractSocket::UnknownSocketError, errorString);
    160             CloseHandle(handleArray[0]);
    161             SetEvent(gotConnectionEvent);
    162             return;
    163         }
    164 
    165         BOOL isConnected = ConnectNamedPipe(handle, &op) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
    166         if (!isConnected) {
    167             switch (WaitForMultipleObjects(2, handleArray, FALSE, INFINITE))
    168             {
    169             case WAIT_OBJECT_0 + 1:
    170                 CloseHandle(handle);
    171                 CloseHandle(handleArray[0]);
     105void QLocalServerPrivate::setError(const QString &function)
     106{
     107    int windowsError = GetLastError();
     108    errorString = QString::fromLatin1("%1: %2").arg(function).arg(qt_error_string(windowsError));
     109    error = QAbstractSocket::UnknownSocketError;
     110}
     111
     112void QLocalServerPrivate::init()
     113{
     114}
     115
     116bool QLocalServerPrivate::removeServer(const QString &name)
     117{
     118    Q_UNUSED(name);
     119    return true;
     120}
     121
     122bool QLocalServerPrivate::listen(const QString &name)
     123{
     124    Q_Q(QLocalServer);
     125
     126    QString pipePath = QLatin1String("\\\\.\\pipe\\");
     127    if (name.startsWith(pipePath))
     128        fullServerName = name;
     129    else
     130        fullServerName = pipePath + name;
     131
     132    // Use only one event for all listeners of one socket.
     133    // The idea is that listener events are rare, so polling all listeners once in a while is
     134    // cheap compared to waiting for N additional events in each iteration of the main loop.
     135    eventHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
     136    connectionEventNotifier = new QWinEventNotifier(eventHandle , q);
     137    q->connect(connectionEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onNewConnection()));
     138
     139    for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i)
     140        if (!addListener())
     141            return false;
     142    return true;
     143}
     144
     145void QLocalServerPrivate::_q_onNewConnection()
     146{
     147    Q_Q(QLocalServer);
     148    DWORD dummy;
     149
     150    // Reset first, otherwise we could reset an event which was asserted
     151    // immediately after we checked the conn status.
     152    ResetEvent(eventHandle);
     153
     154    // Testing shows that there is indeed absolutely no guarantee which listener gets
     155    // a client connection first, so there is no way around polling all of them.
     156    for (int i = 0; i < listeners.size(); ) {
     157        HANDLE handle = listeners[i].handle;
     158        if (GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) {
     159            listeners.removeAt(i);
     160
     161            addListener();
     162
     163            if (pendingConnections.size() > maxPendingConnections)
     164                connectionEventNotifier->setEnabled(false);
     165
     166            // Make this the last thing so connected slots can wreak the least havoc
     167            q->incomingConnection((quintptr)handle);
     168        } else {
     169            if (GetLastError() != ERROR_IO_INCOMPLETE) {
     170                setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
     171                closeServer();
    172172                return;
    173173            }
     174
     175            ++i;
    174176        }
    175         emit connected(handle);
    176         handle = INVALID_HANDLE_VALUE;
    177         ResetEvent(handleArray[0]);
    178         SetEvent(gotConnectionEvent);
    179     }
    180 }
    181 
    182 void QLocalServerPrivate::init()
    183 {
    184     Q_Q(QLocalServer);
    185     qRegisterMetaType<HANDLE>("HANDLE");
    186     q->connect(&waitForConnection, SIGNAL(connected(HANDLE)),
    187                q, SLOT(_q_openSocket(HANDLE)), Qt::QueuedConnection);
    188     q->connect(&waitForConnection, SIGNAL(finished()),
    189                q, SLOT(_q_stoppedListening()), Qt::QueuedConnection);
    190     q->connect(&waitForConnection, SIGNAL(terminated()),
    191                q, SLOT(_q_stoppedListening()), Qt::QueuedConnection);
    192     q->connect(&waitForConnection, SIGNAL(error(QAbstractSocket::SocketError, const QString &)),
    193                q, SLOT(_q_setError(QAbstractSocket::SocketError, const QString &)));
    194 }
    195 
    196 bool QLocalServerPrivate::removeServer(const QString &name)
    197 {
    198     Q_UNUSED(name);
    199     return true;
    200 }
    201 
    202 bool QLocalServerPrivate::listen(const QString &name)
    203 {
    204     fullServerName = waitForConnection.setName(name);
    205     serverName = name;
    206     waitForConnection.start();
    207     return true;
    208 }
    209 
    210 void QLocalServerPrivate::_q_setError(QAbstractSocket::SocketError e, const QString &eString)
    211 {
    212     error = e;
    213     errorString = eString;
    214 }
    215 
    216 void QLocalServerPrivate::_q_stoppedListening()
    217 {
    218     Q_Q(QLocalServer);
    219     if (!inWaitingFunction)
    220         q->close();
    221 }
    222 
    223 void QLocalServerPrivate::_q_openSocket(HANDLE handle)
    224 {
    225     Q_Q(QLocalServer);
    226     q->incomingConnection((int)handle);
     177    }
    227178}
    228179
    229180void QLocalServerPrivate::closeServer()
    230181{
    231     waitForConnection.stop();
    232     waitForConnection.closeServer();
     182    connectionEventNotifier->setEnabled(false); // Otherwise, closed handle is checked before deleter runs
     183    connectionEventNotifier->deleteLater();
     184    connectionEventNotifier = 0;
     185    CloseHandle(eventHandle);
     186    for (int i = 0; i < listeners.size(); ++i)
     187        CloseHandle(listeners[i].handle);
     188    listeners.clear();
    233189}
    234190
     
    239195        return;
    240196
    241     DWORD result = WaitForSingleObject(waitForConnection.gotConnectionEvent,
    242                                        (msecs == -1) ? INFINITE : msecs);
     197    DWORD result = WaitForSingleObject(eventHandle, (msecs == -1) ? INFINITE : msecs);
    243198    if (result == WAIT_TIMEOUT) {
    244199        if (timedOut)
    245200            *timedOut = true;
    246201    } else {
    247         ResetEvent(waitForConnection.gotConnectionEvent);
    248         QCoreApplication::instance()->processEvents();
     202        _q_onNewConnection();
    249203    }
    250204}
  • trunk/src/network/socket/qlocalsocket.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6464    which blocks until the operation is complete or the timeout expires.
    6565
    66     Note that this feature is not supported on Window 9x.
     66    Note that this feature is not supported on versions of Windows earlier than
     67    Windows XP.
    6768
    6869    \sa QLocalServer
     
    103104    specified by \a socketState.
    104105
    105     Note: It is not possible to initialize two local sockets with the same
     106    \note It is not possible to initialize two local sockets with the same
    106107    native socket descriptor.
    107108
     
    208209    returns false.
    209210
    210     Note: The socket's state must be ConnectedState before reading
     211    \note The socket's state must be ConnectedState before reading
    211212    and writing can occur.
    212213
    213     \sa state()
     214    \sa state(), connectToServer()
    214215*/
    215216
     
    244245
    245246/*!
    246     \fn bool QLocalSocket::waitForConnected(int msec)
    247 
    248     Waits until the socket is connected, up to \a msec milliseconds. If the
     247    \fn bool QLocalSocket::waitForConnected(int msecs)
     248
     249    Waits until the socket is connected, up to \a msecs milliseconds. If the
    249250    connection has been established, this function returns true; otherwise
    250251    it returns false. In the case where it returns false, you can call
     
    256257    \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 0
    257258
    258     If msecs is -1, this function will not time out.
     259    If \a msecs is -1, this function will not time out.
    259260
    260261    \sa connectToServer(), connected()
     
    275276    \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 1
    276277
    277     If msecs is -1, this function will not time out.
     278    If \a msecs is -1, this function will not time out.
    278279
    279280    \sa disconnectFromServer(), close()
     
    310311
    311312    QLocalSocket::LocalSocketError is not a registered metatype, so for queued
    312     connections, you will have to register it with Q_DECLARE_METATYPE.
    313 
    314     \sa error(), errorString()
     313    connections, you will have to register it with Q_DECLARE_METATYPE() and
     314    qRegisterMetaType().
     315
     316    \sa error(), errorString(), {Creating Custom Qt Types}
    315317*/
    316318
     
    322324
    323325    QLocalSocket::SocketState is not a registered metatype, so for queued
    324     connections, you will have to register it with Q_DECLARE_METATYPE.
    325 
    326     \sa state()
     326    connections, you will have to register it with Q_DECLARE_METATYPE() and
     327    qRegisterMetaType().
     328
     329    \sa state(), {Creating Custom Qt Types}
    327330*/
    328331
     
    366369    Returns the server path that the socket is connected to.
    367370
    368     Note: This is platform specific
     371    \note The return value of this function is platform specific.
    369372
    370373    \sa connectToServer(), serverName()
     
    469472        break;
    470473    default:
    471         debug << "QLocalSocket::SocketError(" << int(error) << ")";
     474        debug << "QLocalSocket::SocketError(" << int(error) << ')';
    472475        break;
    473476    }
     
    491494        break;
    492495    default:
    493         debug << "QLocalSocket::SocketState(" << int(state) << ")";
     496        debug << "QLocalSocket::SocketState(" << int(state) << ')';
    494497        break;
    495498    }
  • trunk/src/network/socket/qlocalsocket.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    135135    Q_PRIVATE_SLOT(d_func(), void _q_canWrite())
    136136    Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed())
     137    Q_PRIVATE_SLOT(d_func(), void _q_emitReadyRead())
    137138#else
    138139    Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState))
  • trunk/src/network/socket/qlocalsocket_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666#   include "private/qwindowspipewriter_p.h"
    6767#   include "private/qringbuffer_p.h"
     68#   include <private/qwineventnotifier_p.h>
    6869#else
    6970#   include "private/qnativesocketengine_p.h"
     
    7475
    7576QT_BEGIN_NAMESPACE
    76 
    77 #if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
    78 static inline int qSocket(int af, int socketype, int proto)
    79 {
    80     int ret;
    81     while((ret = qt_socket_socket(af, socketype, proto)) == -1 && errno == EINTR){}
    82     return ret;
    83 }
    84 
    85 static inline int qBind(int fd, const sockaddr *sa, int len)
    86 {
    87     int ret;
    88     while((ret = QT_SOCKET_BIND(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){}
    89     return ret;
    90 }
    91 
    92 static inline int qConnect(int fd, const sockaddr *sa, int len)
    93 {
    94     int ret;
    95     while((ret = QT_SOCKET_CONNECT(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){}
    96     return ret;
    97 }
    98 
    99 static inline int qListen(int fd, int backlog)
    100 {
    101     int ret;
    102     while((ret = qt_socket_listen(fd, backlog)) == -1 && errno == EINTR){}
    103     return ret;
    104 }
    105 
    106 static inline int qAccept(int fd, struct sockaddr *addr, QT_SOCKLEN_T *addrlen)
    107 {
    108     int ret;
    109     while((ret = qt_socket_accept(fd, addr, addrlen)) == -1 && errno == EINTR){}
    110     return ret;
    111 }
    112 #endif //#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
    11377
    11478#if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP)
     
    173137    void _q_canWrite();
    174138    void _q_pipeClosed();
    175     qint64 readData(char *data, qint64 maxSize);
    176     qint64 bytesAvailable();
    177     bool readFromSocket();
     139    void _q_emitReadyRead();
     140    DWORD bytesAvailable();
     141    void startAsyncRead();
     142    bool completeAsyncRead();
     143    void checkReadyRead();
    178144    HANDLE handle;
    179145    OVERLAPPED overlapped;
     
    181147    qint64 readBufferMaxSize;
    182148    QRingBuffer readBuffer;
    183     QTimer dataNotifier;
     149    int actualReadBufferSize;
     150    QWinEventNotifier *dataReadNotifier;
    184151    QLocalSocket::LocalSocketError error;
    185     bool readyReadEmitted;
     152    bool readSequenceStarted;
     153    bool pendingReadyRead;
    186154    bool pipeClosed;
     155    static const qint64 initialReadBufferSize = 4096;
    187156#else
    188157    QLocalUnixSocket unixSocket;
     
    193162    void _q_connectToSocket();
    194163    void _q_abortConnectionAttempt();
     164    void cancelDelayedConnect();
    195165    QSocketNotifier *delayConnect;
    196166    QTimer *connectTimer;
  • trunk/src/network/socket/qlocalsocket_tcp.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/network/socket/qlocalsocket_unix.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4242#include "qlocalsocket.h"
    4343#include "qlocalsocket_p.h"
     44#include "qnet_unix_p.h"
    4445
    4546#ifndef QT_NO_LOCALSOCKET
     
    5556#include <qdir.h>
    5657#include <qdebug.h>
     58
     59#ifdef Q_OS_VXWORKS
     60#  include <selectLib.h>
     61#endif
    5762
    5863#define QT_CONNECT_TIMEOUT 30000
     
    233238
    234239    // create the socket
    235     if (-1 == (d->connectingSocket = qSocket(PF_UNIX, SOCK_STREAM, 0))) {
     240    if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) {
    236241        d->errorOccurred(UnsupportedSocketOperationError,
    237242                        QLatin1String("QLocalSocket::connectToServer"));
    238243        return;
    239244    }
    240 
     245#ifndef Q_OS_SYMBIAN
    241246    // set non blocking so we can try to connect and it wont wait
    242247    int flags = fcntl(d->connectingSocket, F_GETFL, 0);
     
    247252        return;
    248253    }
     254#endif
    249255
    250256    // _q_connectToSocket does the actual connecting
     
    283289    ::memcpy(name.sun_path, connectingPathName.toLatin1().data(),
    284290             connectingPathName.toLatin1().size() + 1);
    285     if (-1 == qConnect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) {
     291    if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) {
    286292        QString function = QLatin1String("QLocalSocket::connectToServer");
    287293        switch (errno)
     
    304310            // Try again later, all of the sockets listening are full
    305311            if (!delayConnect) {
    306                 delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write);
     312                delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write, q);
    307313                q->connect(delayConnect, SIGNAL(activated(int)), q, SLOT(_q_connectToSocket()));
    308314            }
     
    323329
    324330    // connected!
    325     if (delayConnect) {
    326         delayConnect->setEnabled(false);
    327         delete delayConnect;
    328         delayConnect = 0;
    329     }
     331    cancelDelayedConnect();
     332
    330333    serverName = connectingName;
    331334    fullServerName = connectingPathName;
     
    374377}
    375378
     379void QLocalSocketPrivate::cancelDelayedConnect()
     380{
     381    if (delayConnect) {
     382        delayConnect->setEnabled(false);
     383        delete delayConnect;
     384        delayConnect = 0;
     385        connectTimer->stop();
     386        delete connectTimer;
     387        connectTimer = 0;
     388    }
     389}
     390
    376391quintptr QLocalSocket::socketDescriptor() const
    377392{
     
    420435    Q_D(QLocalSocket);
    421436    d->unixSocket.close();
    422     if (d->delayConnect) {
    423         d->delayConnect->setEnabled(false);
    424         delete d->delayConnect;
    425         d->delayConnect = 0;
    426         d->connectTimer->stop();
    427         delete d->connectTimer;
    428         d->connectTimer = 0;
    429     }
     437    d->cancelDelayedConnect();
    430438    if (d->connectingSocket != -1)
    431439        ::close(d->connectingSocket);
     
    513521        return (state() == ConnectedState);
    514522
    515     fd_set readfds;
    516     FD_ZERO(&readfds);
    517     FD_SET(d->connectingSocket, &readfds);
     523    fd_set fds;
     524    FD_ZERO(&fds);
     525    FD_SET(d->connectingSocket, &fds);
    518526
    519527    timeval timeout;
     
    531539    while (state() == ConnectingState
    532540           && (-1 == msec || timer.elapsed() < msec)) {
    533         result = ::select(d->connectingSocket + 1, &readfds, 0, 0, &timeout);
     541#ifdef Q_OS_SYMBIAN
     542        // On Symbian, ready-to-write is signaled when non-blocking socket
     543        // connect is finised. Is ready-to-read really used on other
     544        // UNIX paltforms when using non-blocking AF_UNIX socket?
     545        result = ::select(d->connectingSocket + 1, 0, &fds, 0, &timeout);
     546#else
     547        result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout);
     548#endif
    534549        if (-1 == result && errno != EINTR) {
    535550            d->errorOccurred( QLocalSocket::UnknownSocketError,
  • trunk/src/network/socket/qlocalsocket_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949QT_BEGIN_NAMESPACE
    5050
    51 #define NOTIFYTIMEOUT 100
    52 
    5351void QLocalSocketPrivate::init()
    5452{
    5553    Q_Q(QLocalSocket);
    56     QObject::connect(&dataNotifier, SIGNAL(timeout()), q, SLOT(_q_notified()));
     54    memset(&overlapped, 0, sizeof(overlapped));
    5755    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     56    dataReadNotifier = new QWinEventNotifier(overlapped.hEvent, q);
     57    q->connect(dataReadNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_notified()));
    5858}
    5959
     
    102102       pipeWriter(0),
    103103       readBufferMaxSize(0),
     104       actualReadBufferSize(0),
    104105       error(QLocalSocket::UnknownSocketError),
    105        readyReadEmitted(false),
     106       readSequenceStarted(false),
     107       pendingReadyRead(false),
    106108       pipeClosed(false),
    107109       state(QLocalSocket::UnconnectedState)
     
    138140        DWORD permissions = (openMode & QIODevice::ReadOnly) ? GENERIC_READ : 0;
    139141        permissions |= (openMode & QIODevice::WriteOnly) ? GENERIC_WRITE : 0;
    140         QT_WA({
    141         localSocket = CreateFileW(
    142                        (TCHAR*)d->fullServerName.utf16(),   // pipe name
    143                        permissions,
    144                        0,              // no sharing
    145                        NULL,           // default security attributes
    146                        OPEN_EXISTING,  // opens existing pipe
    147                        0,              // default attributes
    148                        NULL);          // no template file
    149         }, {
    150         localSocket = CreateFileA(
    151                        d->fullServerName.toLocal8Bit().constData(), // pipe name
    152                        permissions,
    153                        0,              // no sharing
    154                        NULL,           // default security attributes
    155                        OPEN_EXISTING,  // opens existing pipe
    156                        0,              // default attributes
    157                        NULL);          // no template file
    158         });
     142        localSocket = CreateFile((const wchar_t *)d->fullServerName.utf16(),   // pipe name
     143                                 permissions,
     144                                 0,              // no sharing
     145                                 NULL,           // default security attributes
     146                                 OPEN_EXISTING,  // opens existing pipe
     147                                 FILE_FLAG_OVERLAPPED,
     148                                 NULL);          // no template file
     149
    159150        if (localSocket != INVALID_HANDLE_VALUE)
    160151            break;
     
    166157
    167158        // All pipe instances are busy, so wait until connected or up to 5 seconds.
    168         QT_WA({
    169             if (!WaitNamedPipeW((TCHAR*)d->fullServerName.utf16(), 5000))
    170                 break;
    171         }, {
    172             if (!WaitNamedPipeA(d->fullServerName.toLocal8Bit().constData(), 5000))
    173                 break;
    174         });
     159        if (!WaitNamedPipe((const wchar_t *)d->fullServerName.utf16(), 5000))
     160            break;
    175161    }
    176162
     
    183169    // we have a valid handle
    184170    d->serverName = name;
    185     if (setSocketDescriptor((quintptr)localSocket), openMode) {
     171    if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) {
    186172        d->handle = localSocket;
    187173        emit connected();
     
    193179{
    194180    Q_D(QLocalSocket);
    195     if (d->readBuffer.isEmpty()) {
    196         if (!d->readFromSocket()) {
    197             if (d->pipeClosed)
    198                 return -1;
    199             return 0;
    200         }
    201     }
    202 
    203     if (!d->dataNotifier.isActive() && d->threadData->eventDispatcher)
    204         d->dataNotifier.start(NOTIFYTIMEOUT);
    205 
    206     if (d->readBuffer.isEmpty())
    207         return qint64(0);
    208 
    209     // If readFromSocket() read data, copy it to its destination.
    210     if (maxSize == 1) {
     181
     182    qint64 readSoFar;
     183    // If startAsyncRead() read data, copy it to its destination.
     184    if (maxSize == 1 && d->actualReadBufferSize > 0) {
    211185        *data = d->readBuffer.getChar();
    212         return 1;
    213     }
    214 
    215     qint64 bytesToRead = qMin(qint64(d->readBuffer.size()), maxSize);
    216     qint64 readSoFar = 0;
    217     while (readSoFar < bytesToRead) {
    218         const char *ptr = d->readBuffer.readPointer();
    219         int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar),
    220                                             d->readBuffer.nextDataBlockSize());
    221         memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
    222         readSoFar += bytesToReadFromThisBlock;
    223         d->readBuffer.free(bytesToReadFromThisBlock);
    224     }
     186        d->actualReadBufferSize--;
     187        readSoFar = 1;
     188    } else {
     189        qint64 bytesToRead = qMin(qint64(d->actualReadBufferSize), maxSize);
     190        readSoFar = 0;
     191        while (readSoFar < bytesToRead) {
     192            const char *ptr = d->readBuffer.readPointer();
     193            int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
     194                                                qint64(d->readBuffer.nextDataBlockSize()));
     195            memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
     196            readSoFar += bytesToReadFromThisBlock;
     197            d->readBuffer.free(bytesToReadFromThisBlock);
     198            d->actualReadBufferSize -= bytesToReadFromThisBlock;
     199        }
     200    }
     201
     202    if (d->pipeClosed) {
     203        if (readSoFar == 0) {
     204            QTimer::singleShot(0, this, SLOT(_q_pipeClosed()));
     205            return -1;  // signal EOF
     206        }
     207    } else {
     208        if (!d->readSequenceStarted)
     209            d->startAsyncRead();
     210        d->checkReadyRead();
     211    }
     212
    225213    return readSoFar;
    226214}
     
    228216/*!
    229217    \internal
    230     read from the socket
     218    Schedules or cancels a readyRead() emission depending on actual data availability
    231219 */
    232 qint64 QLocalSocketPrivate::readData(char *data, qint64 maxSize)
    233 {
    234     DWORD bytesRead = 0;
    235     overlapped.Offset = 0;
    236     overlapped.OffsetHigh = 0;
    237     bool success = ReadFile(handle, data, maxSize, &bytesRead, &overlapped);
    238     if (!success && GetLastError() == ERROR_IO_PENDING)
    239         if (GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE))
    240             success = true;
    241     if (!success) {
    242         setErrorString(QLatin1String("QLocalSocket::readData"));
    243         return 0;
    244     }
    245     return bytesRead;
     220void QLocalSocketPrivate::checkReadyRead()
     221{
     222    if (actualReadBufferSize > 0) {
     223        if (!pendingReadyRead) {
     224            Q_Q(QLocalSocket);
     225            QTimer::singleShot(0, q, SLOT(_q_emitReadyRead()));
     226            pendingReadyRead = true;
     227        }
     228    } else {
     229        pendingReadyRead = false;
     230    }
    246231}
    247232
     
    250235    Reads data from the socket into the readbuffer
    251236 */
    252 bool QLocalSocketPrivate::readFromSocket()
    253 {
    254     qint64 bytesToRead = bytesAvailable();
    255     if (bytesToRead == 0)
     237void QLocalSocketPrivate::startAsyncRead()
     238{
     239    do {
     240        DWORD bytesToRead = bytesAvailable();
     241        if (bytesToRead == 0) {
     242            // There are no bytes in the pipe but we need to
     243            // start the overlapped read with some buffer size.
     244            bytesToRead = initialReadBufferSize;
     245        }
     246
     247        if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
     248            bytesToRead = readBufferMaxSize - readBuffer.size();
     249            if (bytesToRead == 0) {
     250                // Buffer is full. User must read data from the buffer
     251                // before we can read more from the pipe.
     252                return;
     253            }
     254        }
     255
     256        char *ptr = readBuffer.reserve(bytesToRead);
     257
     258        readSequenceStarted = true;
     259        if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) {
     260            completeAsyncRead();
     261        } else {
     262            switch (GetLastError()) {
     263                case ERROR_IO_PENDING:
     264                    // This is not an error. We're getting notified, when data arrives.
     265                    return;
     266                case ERROR_PIPE_NOT_CONNECTED:
     267                    {
     268                        // It may happen, that the other side closes the connection directly
     269                        // after writing data. Then we must set the appropriate socket state.
     270                        pipeClosed = true;
     271                        Q_Q(QLocalSocket);
     272                        emit q->readChannelFinished();
     273                        return;
     274                    }
     275                default:
     276                    setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead"));
     277                    return;
     278            }
     279        }
     280    } while (!readSequenceStarted);
     281}
     282
     283/*!
     284    \internal
     285    Sets the correct size of the read buffer after a read operation.
     286    Returns false, if an error occured or the connection dropped.
     287 */
     288bool QLocalSocketPrivate::completeAsyncRead()
     289{
     290    ResetEvent(overlapped.hEvent);
     291    readSequenceStarted = false;
     292
     293    DWORD bytesRead;
     294    if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) {
     295        if (GetLastError() != ERROR_PIPE_NOT_CONNECTED)
     296            setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead"));
    256297        return false;
    257 
    258     if (readBufferMaxSize && bytesToRead
    259                      > (readBufferMaxSize - readBuffer.size()))
    260         bytesToRead = readBufferMaxSize - readBuffer.size();
    261 
    262     char *ptr = readBuffer.reserve(bytesToRead);
    263     qint64 readBytes = readData(ptr, bytesToRead);
    264     if (readBytes == 0) {
    265         readBuffer.chop(bytesToRead);
    266         return false;
    267     }
    268     readyReadEmitted = false;
    269     readBuffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes)));
     298    }
     299
     300    actualReadBufferSize += bytesRead;
     301    readBuffer.truncate(actualReadBufferSize);
    270302    return true;
    271303}
     
    276308    if (!d->pipeWriter) {
    277309        d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
     310        connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));
     311        connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64)));
    278312        d->pipeWriter->start();
    279         connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));
    280313    }
    281314    return d->pipeWriter->write(data, maxSize);
     
    290323    The number of bytes available from the pipe
    291324  */
    292 qint64 QLocalSocketPrivate::bytesAvailable()
     325DWORD QLocalSocketPrivate::bytesAvailable()
    293326{
    294327    Q_Q(QLocalSocket);
    295     if (q->state() != QLocalSocket::ConnectedState)
    296         return 0;
    297328    DWORD bytes;
    298329    if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) {
    299330        return bytes;
    300331    } else {
    301         if (ERROR_BROKEN_PIPE == GetLastError() && !pipeClosed) {
     332        if (!pipeClosed) {
    302333            pipeClosed = true;
     334            emit q->readChannelFinished();
    303335            QTimer::singleShot(0, q, SLOT(_q_pipeClosed()));
    304336        }
     
    317349    Q_D(const QLocalSocket);
    318350    qint64 available = QIODevice::bytesAvailable();
    319     available += (qint64) d->readBuffer.size();
     351    available += (qint64) d->actualReadBufferSize;
    320352    return available;
    321353}
     
    332364    if (state() != ConnectedState)
    333365        return false;
    334     return (d->readBuffer.indexOf('\n') != -1 || QIODevice::canReadLine());
     366    return (QIODevice::canReadLine()
     367            || d->readBuffer.indexOf('\n', d->actualReadBufferSize) != -1);
    335368}
    336369
     
    344377    d->state = ClosingState;
    345378    emit stateChanged(d->state);
    346     d->readyReadEmitted = false;
    347     emit readChannelFinished();
     379    if (!d->pipeClosed)
     380        emit readChannelFinished();
    348381    d->serverName = QString();
    349382    d->fullServerName = QString();
     
    353386        return;
    354387    }
     388    d->readSequenceStarted = false;
     389    d->pendingReadyRead = false;
    355390    d->pipeClosed = false;
    356391    DisconnectNamedPipe(d->handle);
    357392    CloseHandle(d->handle);
    358393    d->handle = INVALID_HANDLE_VALUE;
     394    ResetEvent(d->overlapped.hEvent);
    359395    d->state = UnconnectedState;
    360396    emit stateChanged(d->state);
     
    364400        d->pipeWriter = 0;
    365401    }
    366     d->dataNotifier.stop();
    367402}
    368403
     
    398433    Q_D(QLocalSocket);
    399434    d->readBuffer.clear();
     435    d->actualReadBufferSize = 0;
    400436    QIODevice::open(openMode);
    401437    d->handle = (int*)socketDescriptor;
    402438    d->state = socketState;
    403439    emit stateChanged(d->state);
    404     if (d->threadData->eventDispatcher)
    405         d->dataNotifier.start(NOTIFYTIMEOUT);
     440    if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) {
     441        d->startAsyncRead();
     442        d->checkReadyRead();
     443    }
    406444    return true;
    407445}
     
    417455{
    418456    Q_Q(QLocalSocket);
    419     if (0 != bytesAvailable()) {
    420         if (readBufferMaxSize == 0 || readBuffer.size() < readBufferMaxSize) {
    421             if (!readFromSocket()) {
    422                 return;
    423             }
    424             // wait until buffer is cleared before starting again
    425             if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize) {
    426                 dataNotifier.stop();
    427             }
    428         }
    429         if (!readyReadEmitted) {
    430             readyReadEmitted = true;
    431             q->emit readyRead();
    432         }
     457    if (!completeAsyncRead()) {
     458        pipeClosed = true;
     459        emit q->readChannelFinished();
     460        return;
     461    }
     462    startAsyncRead();
     463    pendingReadyRead = false;
     464    emit q->readyRead();
     465}
     466
     467void QLocalSocketPrivate::_q_emitReadyRead()
     468{
     469    if (pendingReadyRead) {
     470        Q_Q(QLocalSocket);
     471        pendingReadyRead = false;
     472        emit q->readyRead();
    433473    }
    434474}
     
    463503    if (state() == UnconnectedState)
    464504        return false;
     505    if (!openMode().testFlag(QIODevice::ReadOnly)) {
     506        qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes.");
     507        return false;
     508    }
    465509    QIncrementalSleepTimer timer(msecs);
    466510    forever {
    467         d->_q_notified();
    468         if (d->pipeClosed)
    469             close();
     511        d->bytesAvailable();    // to check if PeekNamedPipe fails
     512        if (d->pipeClosed)
     513            close();
    470514        if (state() == UnconnectedState)
    471515            return true;
     
    487531{
    488532    Q_D(QLocalSocket);
    489     QIncrementalSleepTimer timer(msecs);
    490     forever {
    491         d->_q_notified();
    492         if (bytesAvailable() > 0) {
    493             if (!d->readyReadEmitted) {
    494                 d->readyReadEmitted = true;
    495                 emit readyRead();
    496             }
     533
     534    if (bytesAvailable() > 0)
     535        return true;
     536
     537    if (d->state != QLocalSocket::ConnectedState)
     538        return false;
     539
     540    Q_ASSERT(d->readSequenceStarted);
     541    DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs);
     542    switch (result) {
     543        case WAIT_OBJECT_0:
     544            d->_q_notified();
    497545            return true;
    498         }
    499 
    500         Sleep(timer.nextSleepTime());
    501         if (timer.hasTimedOut())
    502             break;
    503     }
    504 
     546        case WAIT_TIMEOUT:
     547            return false;
     548    }
     549
     550    qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", int(GetLastError()));
    505551    return false;
    506552}
     
    512558        return false;
    513559
    514     QIncrementalSleepTimer timer(msecs);
    515     forever {
    516         if (d->pipeWriter->hadWritten())
    517             return true;
    518 
    519         if (d->pipeWriter->bytesToWrite() == 0)
    520             return false;
    521 
    522         // Wait for the pipe writer to acknowledge that it has
    523         // written. This will succeed if either the pipe writer has
    524         // already written the data, or if it manages to write data
    525         // within the given timeout.
    526         if (d->pipeWriter->waitForWrite(0))
    527             return true;
    528 
    529         Sleep(timer.nextSleepTime());
    530         if (timer.hasTimedOut())
    531             break;
    532     }
    533 
    534     return false;
     560    // Wait for the pipe writer to acknowledge that it has
     561    // written. This will succeed if either the pipe writer has
     562    // already written the data, or if it manages to write data
     563    // within the given timeout.
     564    return d->pipeWriter->waitForWrite(msecs);
    535565}
    536566
  • trunk/src/network/socket/qnativesocketengine.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848
    4949    \reentrant
    50     \ingroup io
     50    \ingroup network
    5151    \inmodule QtNetwork
    5252
     
    195195    switch (errorString) {
    196196    case NonBlockingInitFailedErrorString:
    197         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize non-blocking socket"));
     197        socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket");
    198198        break;
    199199    case BroadcastingInitFailedErrorString:
    200         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize broadcast socket"));
     200        socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket");
    201201        break;
    202202    case NoIpV6ErrorString:
    203         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Attempt to use IPv6 socket on a platform with no IPv6 support"));
     203        socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support");
    204204        break;
    205205    case RemoteHostClosedErrorString:
    206         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The remote host closed the connection"));
     206        socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection");
    207207        break;
    208208    case TimeOutErrorString:
    209         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network operation timed out"));
     209        socketErrorString = QNativeSocketEngine::tr("Network operation timed out");
    210210        break;
    211211    case ResourceErrorString:
    212         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Out of resources"));
     212        socketErrorString = QNativeSocketEngine::tr("Out of resources");
    213213        break;
    214214    case OperationUnsupportedErrorString:
    215         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unsupported socket operation"));
     215        socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation");
    216216        break;
    217217    case ProtocolUnsupportedErrorString:
    218         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Protocol type not supported"));
     218        socketErrorString = QNativeSocketEngine::tr("Protocol type not supported");
    219219        break;
    220220    case InvalidSocketErrorString:
    221         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Invalid socket descriptor"));
     221        socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor");
    222222        break;
    223223    case HostUnreachableErrorString:
    224         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Host unreachable"));
     224        socketErrorString = QNativeSocketEngine::tr("Host unreachable");
    225225        break;
    226226    case NetworkUnreachableErrorString:
    227         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network unreachable"));
     227        socketErrorString = QNativeSocketEngine::tr("Network unreachable");
    228228        break;
    229229    case AccessErrorString:
    230         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Permission denied"));
     230        socketErrorString = QNativeSocketEngine::tr("Permission denied");
    231231        break;
    232232    case ConnectionTimeOutErrorString:
    233         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection timed out"));
     233        socketErrorString = QNativeSocketEngine::tr("Connection timed out");
    234234        break;
    235235    case ConnectionRefusedErrorString:
    236         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection refused"));
     236        socketErrorString = QNativeSocketEngine::tr("Connection refused");
    237237        break;
    238238    case AddressInuseErrorString:
    239         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The bound address is already in use"));
     239        socketErrorString = QNativeSocketEngine::tr("The bound address is already in use");
    240240        break;
    241241    case AddressNotAvailableErrorString:
    242         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is not available"));
     242        socketErrorString = QNativeSocketEngine::tr("The address is not available");
    243243        break;
    244244    case AddressProtectedErrorString:
    245         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is protected"));
     245        socketErrorString = QNativeSocketEngine::tr("The address is protected");
    246246        break;
    247247    case DatagramTooLargeErrorString:
    248         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Datagram was too large to send"));
     248        socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send");
    249249        break;
    250250    case SendDatagramErrorString:
    251         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to send a message"));
     251        socketErrorString = QNativeSocketEngine::tr("Unable to send a message");
    252252        break;
    253253    case ReceiveDatagramErrorString:
    254         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to receive a message"));
     254        socketErrorString = QNativeSocketEngine::tr("Unable to receive a message");
    255255        break;
    256256    case WriteErrorString:
    257         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to write"));
     257        socketErrorString = QNativeSocketEngine::tr("Unable to write");
    258258        break;
    259259    case ReadErrorString:
    260         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network error"));
     260        socketErrorString = QNativeSocketEngine::tr("Network error");
    261261        break;
    262262    case PortInuseErrorString:
    263         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Another socket is already listening on the same port"));
     263        socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port");
    264264        break;
    265265    case NotSocketErrorString:
    266         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Operation on non-socket"));
     266        socketErrorString = QNativeSocketEngine::tr("Operation on non-socket");
    267267        break;
    268268    case InvalidProxyTypeString:
    269         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The proxy type is invalid for this operation"));
     269        socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation");
    270270        break;
    271271    case UnknownSocketErrorString:
    272         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unknown error"));
     272        socketErrorString = QNativeSocketEngine::tr("Unknown error");
    273273        break;
    274274    }
     
    382382    }
    383383
     384
    384385    // Make sure we receive out-of-band data
     386    // On Symbian OS this works only with native IP stack, not with WinSock
    385387    if (socketType == QAbstractSocket::TcpSocket
    386388        && !setOption(ReceiveOutOfBandData, 1)) {
     
    388390    }
    389391
    390     // Set the send and receive buffer sizes to a magic size, found
    391     // most optimal for our platforms.
    392     setReceiveBufferSize(49152);
    393     setSendBufferSize(49152);
     392    // Before Qt 4.6, we always set the send and receive buffer size to 49152 as
     393    // this was found to be an optimal value. However, modern OS
     394    // all have some kind of auto tuning for this and we therefore don't set
     395    // this explictly anymore.
     396    // If it introduces any performance regressions for Qt 4.6.x (x > 0) then
     397    // it will be put back in.
     398    //
     399    // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed
     400    // with this.
     401    //
     402    // pre-4.6:
     403    // setReceiveBufferSize(49152);
     404    // setSendBufferSize(49152);
    394405
    395406    d->socketType = socketType;
     
    744755}
    745756
     757
     758qint64 QNativeSocketEngine::bytesToWrite() const
     759{
     760    return 0;
     761}
     762
    746763/*!
    747764    Reads up to \a maxSize bytes into \a data from the socket.
     
    860877bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
    861878{
    862     Q_D(const QNativeSocketEngine);
     879    Q_D(QNativeSocketEngine);
    863880    Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
    864881    Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(),
     
    877894        d_func()->fetchConnectionParameters();
    878895        return true;
     896    } else {
     897        int value = 0;
     898        int valueSize = sizeof(value);
     899        if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
     900            if (value == WSAECONNREFUSED) {
     901                d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
     902                d->socketState = QAbstractSocket::UnconnectedState;
     903                return false;
     904            } else if (value == WSAETIMEDOUT) {
     905                d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
     906                d->socketState = QAbstractSocket::UnconnectedState;
     907                return false;
     908            } else if (value == WSAEHOSTUNREACH) {
     909                d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
     910                d->socketState = QAbstractSocket::UnconnectedState;
     911                return false;
     912            }
     913        }
    879914    }
    880915#endif
     
    897932                                      int msecs, bool *timedOut)
    898933{
    899     Q_D(const QNativeSocketEngine);
     934    Q_D(QNativeSocketEngine);
    900935    Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
    901936    Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(),
     
    911946        d_func()->fetchConnectionParameters();
    912947        return true;
    913     }
    914 #endif   
     948    } else {
     949        int value = 0;
     950        int valueSize = sizeof(value);
     951        if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
     952            if (value == WSAECONNREFUSED) {
     953                d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
     954                d->socketState = QAbstractSocket::UnconnectedState;
     955                return false;
     956            } else if (value == WSAETIMEDOUT) {
     957                d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
     958                d->socketState = QAbstractSocket::UnconnectedState;
     959                return false;
     960            } else if (value == WSAEHOSTUNREACH) {
     961                d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
     962                d->socketState = QAbstractSocket::UnconnectedState;
     963                return false;
     964            }
     965        }
     966    }
     967#endif
    915968    if (ret == 0) {
    916969        if (timedOut)
     
    10871140{
    10881141    if (e->type() == QEvent::SockAct) {
    1089         engine->exceptionNotification();
     1142        if (engine->state() == QAbstractSocket::ConnectingState)
     1143            engine->connectionNotification();
     1144        else
     1145            engine->exceptionNotification();
    10901146        return true;
    10911147    }
  • trunk/src/network/socket/qnativesocketengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5353// We mean it.
    5454//
    55 
    5655#include "QtNetwork/qhostaddress.h"
    5756#include "private/qabstractsocketengine_p.h"
    5857#ifndef Q_OS_WIN
    59 #include "qplatformdefs.h"
     58#  include "qplatformdefs.h"
     59#else
     60#  include <winsock2.h>
     61#endif
     62
     63#ifdef Q_OS_SYMBIAN
     64#include <private/qeventdispatcher_symbian_p.h>
     65#include <unistd.h>
    6066#endif
    6167
    6268QT_BEGIN_NAMESPACE
    6369
    64 #ifndef Q_OS_WIN
    65 // Almost always the same. If not, specify in qplatformdefs.h.
    66 #if !defined(QT_SOCKOPTLEN_T)
    67 # define QT_SOCKOPTLEN_T QT_SOCKLEN_T
    68 #endif
    69 
    70 // Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED
    71 static inline int qt_socket_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen)
    72 { return ::accept(s, addr, static_cast<QT_SOCKLEN_T *>(addrlen)); }
    73 #if defined(accept)
    74 # undef accept
    75 #endif
    76 
    77 // UnixWare 7 redefines listen -> _listen
    78 static inline int qt_socket_listen(int s, int backlog)
    79 { return ::listen(s, backlog); }
    80 #if defined(listen)
    81 # undef listen
    82 #endif
    83 
    84 // UnixWare 7 redefines socket -> _socket
    85 static inline int qt_socket_socket(int domain, int type, int protocol)
    86 { return ::socket(domain, type, protocol); }
    87 #if defined(socket)
    88 # undef socket
    89 #endif
    90 
    91 #endif
     70// Use our own defines and structs which we know are correct
     71#  define QT_SS_MAXSIZE 128
     72#  define QT_SS_ALIGNSIZE (sizeof(qint64))
     73#  define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short))
     74#  define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE))
     75struct qt_sockaddr_storage {
     76      short ss_family;
     77      char __ss_pad1[QT_SS_PAD1SIZE];
     78      qint64 __ss_align;
     79      char __ss_pad2[QT_SS_PAD2SIZE];
     80};
     81
     82// sockaddr_in6 size changed between old and new SDK
     83// Only the new version is the correct one, so always
     84// use this structure.
     85struct qt_in6_addr {
     86    quint8 qt_s6_addr[16];
     87};
     88struct qt_sockaddr_in6 {
     89    short   sin6_family;            /* AF_INET6 */
     90    quint16 sin6_port;              /* Transport level port number */
     91    quint32 sin6_flowinfo;          /* IPv6 flow information */
     92    struct  qt_in6_addr sin6_addr;  /* IPv6 address */
     93    quint32 sin6_scope_id;          /* set of interfaces for a scope */
     94};
     95
     96union qt_sockaddr {
     97    sockaddr a;
     98    sockaddr_in a4;
     99    qt_sockaddr_in6 a6;
     100    qt_sockaddr_storage storage;
     101};
    92102
    93103class QNativeSocketEnginePrivate;
     
    125135    bool hasPendingDatagrams() const;
    126136    qint64 pendingDatagramSize() const;
     137
     138    qint64 bytesToWrite() const;
    127139
    128140    qint64 receiveBufferSize() const;
  • trunk/src/network/socket/qnativesocketengine_unix.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4141
    4242//#define QNATIVESOCKETENGINE_DEBUG
    43 
    4443#include "qnativesocketengine_p.h"
     44#include "private/qnet_unix_p.h"
    4545#include "qiodevice.h"
    4646#include "qhostaddress.h"
     
    6363#include <qstring.h>
    6464#include <ctype.h>
     65#endif
     66
     67#ifdef Q_OS_SYMBIAN // ### TODO: Are these headers right?
     68#include <sys/socket.h>
     69#include <netinet/in.h>
     70#else
     71#include <netinet/tcp.h>
    6572#endif
    6673
     
    101108static void qt_ignore_sigpipe()
    102109{
     110#ifndef Q_NO_POSIX_SIGNALS
    103111    // Set to ignore SIGPIPE once only.
    104112    static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
     
    109117        ::sigaction(SIGPIPE, &noaction, 0);
    110118    }
     119#else
     120    // Posix signals are not supported by the underlying platform
     121    // so we don't need to ignore sigpipe signal explicitly
     122#endif
    111123}
    112124
     
    115127    \a port and \a addr if they are non-null.
    116128*/
    117 static inline void qt_socket_getPortAndAddress(struct sockaddr *sa, quint16 *port, QHostAddress *addr)
     129static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *port, QHostAddress *addr)
    118130{
    119131#if !defined(QT_NO_IPV6)
    120     if (sa->sa_family == AF_INET6) {
    121         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
     132    if (s->a.sa_family == AF_INET6) {
    122133        Q_IPV6ADDR tmp;
    123         memcpy(&tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp));
     134        memcpy(&tmp, &s->a6.sin6_addr, sizeof(tmp));
    124135        if (addr) {
    125136            QHostAddress tmpAddress;
     
    128139#ifndef QT_NO_IPV6IFNAME
    129140            char scopeid[IFNAMSIZ];
    130             if (::if_indextoname(sa6->sin6_scope_id, scopeid) > 0) {
     141            if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) {
    131142                addr->setScopeId(QLatin1String(scopeid));
    132143            } else
    133144#endif
    134             addr->setScopeId(QString::number(sa6->sin6_scope_id));
     145            addr->setScopeId(QString::number(s->a6.sin6_scope_id));
    135146        }
    136147        if (port)
    137             *port = ntohs(sa6->sin6_port);
     148            *port = ntohs(s->a6.sin6_port);
    138149        return;
    139150    }
    140151#endif
    141     struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
    142152    if (port)
    143         *port = ntohs(sa4->sin_port);
     153        *port = ntohs(s->a4.sin_port);
    144154    if (addr) {
    145155        QHostAddress tmpAddress;
    146         tmpAddress.setAddress(ntohl(sa4->sin_addr.s_addr));
     156        tmpAddress.setAddress(ntohl(s->a4.sin_addr.s_addr));
    147157        *addr = tmpAddress;
    148158    }
     
    164174#endif
    165175    int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
    166     int socket = qt_socket_socket(protocol, type, 0);
     176#ifdef Q_OS_SYMBIAN
     177    int socket = ::socket(protocol, type, 0);
     178#else
     179        int socket = qt_safe_socket(protocol, type, 0);
     180#endif
    167181
    168182    if (socket <= 0) {
     
    191205    // Ensure that the socket is closed on exec*().
    192206    ::fcntl(socket, F_SETFD, FD_CLOEXEC);
     207
    193208    socketDescriptor = socket;
    194209    return true;
     
    205220
    206221    int n = -1;
     222    int level = SOL_SOCKET; // default
     223
    207224    switch (opt) {
    208225    case QNativeSocketEngine::ReceiveBufferSocketOption:
     
    224241        n = SO_OOBINLINE;
    225242        break;
     243    case QNativeSocketEngine::LowDelayOption:
     244        level = IPPROTO_TCP;
     245        n = TCP_NODELAY;
     246        break;
     247    case QNativeSocketEngine::KeepAliveOption:
     248        n = SO_KEEPALIVE;
     249        break;
    226250    }
    227251
    228252    int v = -1;
    229253    QT_SOCKOPTLEN_T len = sizeof(v);
    230     if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)
     254    if (::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
    231255        return v;
     256
    232257    return -1;
    233258}
     
    244269
    245270    int n = 0;
     271    int level = SOL_SOCKET; // default
     272
    246273    switch (opt) {
    247274    case QNativeSocketEngine::ReceiveBufferSocketOption:
     
    256283    case QNativeSocketEngine::NonBlockingSocketOption: {
    257284        // Make the socket nonblocking.
     285#if !defined(Q_OS_VXWORKS)
    258286        int flags = ::fcntl(socketDescriptor, F_GETFL, 0);
    259287        if (flags == -1) {
     
    269297            return false;
    270298        }
    271 
     299#else // Q_OS_VXWORKS
     300        int onoff = 1;
     301#ifdef Q_OS_SYMBIAN
     302        if (::ioctl(socketDescriptor, FIONBIO, &onoff) < 0) {
     303#else
     304        if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) {
     305#endif
     306#ifdef QNATIVESOCKETENGINE_DEBUG
     307            perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed");
     308#endif
     309            return false;
     310        }
     311#endif // Q_OS_VXWORKS
    272312        return true;
    273313    }
    274314    case QNativeSocketEngine::AddressReusable:
    275 #ifdef SO_REUSEPORT
     315#if defined(SO_REUSEPORT) && !defined(Q_OS_SYMBIAN)
    276316        n = SO_REUSEPORT;
    277317#else
     
    284324        n = SO_OOBINLINE;
    285325        break;
    286     }
    287 
    288     return ::setsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, sizeof(v)) == 0;
     326    case QNativeSocketEngine::LowDelayOption:
     327        level = IPPROTO_TCP;
     328        n = TCP_NODELAY;
     329        break;
     330    case QNativeSocketEngine::KeepAliveOption:
     331        n = SO_KEEPALIVE;
     332        break;
     333    }
     334
     335    return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
    289336}
    290337
    291338bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port)
    292339{
     340#ifdef QNATIVESOCKETENGINE_DEBUG
     341    qDebug("QNativeSocketEnginePrivate::nativeConnect() : %d ", socketDescriptor);
     342#endif
     343
    293344    struct sockaddr_in sockAddrIPv4;
    294345    struct sockaddr *sockAddrPtr = 0;
     
    328379        // unreachable
    329380    }
    330 
    331     int connectResult = QT_SOCKET_CONNECT(socketDescriptor, sockAddrPtr, sockAddrSize);
     381#ifdef Q_OS_SYMBIAN
     382    int connectResult = ::connect(socketDescriptor, sockAddrPtr, sockAddrSize);
     383#else
     384    int connectResult = qt_safe_connect(socketDescriptor, sockAddrPtr, sockAddrSize);
     385#endif
    332386    if (connectResult == -1) {
    333387        switch (errno) {
     
    433487
    434488    int bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, sockAddrSize);
     489
    435490    if (bindResult < 0) {
    436491        switch(errno) {
     
    469524bool QNativeSocketEnginePrivate::nativeListen(int backlog)
    470525{
    471     if (qt_socket_listen(socketDescriptor, backlog) < 0) {
     526#ifdef Q_OS_SYMBIAN
     527    if (::listen(socketDescriptor, backlog) < 0) {
     528#else
     529    if (qt_safe_listen(socketDescriptor, backlog) < 0) {
     530#endif
    472531        switch (errno) {
    473532        case EADDRINUSE:
     
    496555int QNativeSocketEnginePrivate::nativeAccept()
    497556{
    498     int acceptedDescriptor = qt_socket_accept(socketDescriptor, 0, 0);
    499 #if defined (QNATIVESOCKETENGINE_DEBUG)
    500     qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor);
    501 #endif
    502     // Ensure that the socket is closed on exec*()
    503     ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC);
     557#ifdef Q_OS_SYMBIAN
     558    int acceptedDescriptor = ::accept(socketDescriptor, 0, 0);
     559#else
     560    int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0);
     561#endif
     562    //check if we have vaild descriptor at all
     563    if(acceptedDescriptor > 0) {
     564        // Ensure that the socket is closed on exec*()
     565        ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC);
     566    }
     567#ifdef Q_OS_SYMBIAN
     568    else {
     569        qWarning("QNativeSocketEnginePrivate::nativeAccept() - acceptedDescriptor <= 0");
     570    }
     571#endif
     572
    504573    return acceptedDescriptor;
    505574}
     
    507576qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
    508577{
    509     /*
    510       Apparently, there is not consistency among different operating
    511       systems on how to use FIONREAD.
    512 
    513       FreeBSD, Linux and Solaris all expect the 3rd argument to
    514       ioctl() to be an int, which is normally 32-bit even on 64-bit
    515       machines.
    516 
    517       IRIX, on the other hand, expects a size_t, which is 64-bit on
    518       64-bit machines.
    519 
    520       So, the solution is to use size_t initialized to zero to make
    521       sure all bits are set to zero, preventing underflow with the
    522       FreeBSD/Linux/Solaris ioctls.
    523     */
    524     size_t nbytes = 0;
     578    int nbytes = 0;
    525579    // gives shorter than true amounts on Unix domain sockets.
    526580    qint64 available = 0;
    527     if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
    528         available = (qint64) *((int *) &nbytes);
     581#ifdef Q_OS_SYMBIAN
     582        if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
     583#else
     584    if (qt_safe_ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)
     585#endif
     586        available = (qint64) nbytes;
    529587
    530588#if defined (QNATIVESOCKETENGINE_DEBUG)
     
    537595{
    538596    // Create a sockaddr struct and reset its port number.
    539 #if !defined(QT_NO_IPV6)
    540     struct sockaddr_storage storage;
    541     sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<sockaddr_in6 *>(&storage);
    542     storagePtrIPv6->sin6_port = 0;
    543 #else
    544     struct sockaddr storage;
    545 #endif
    546     sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage);
    547     storagePtr->sa_family = 0;
    548 
    549     sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage);
    550     storagePtrIPv4->sin_port = 0;
     597    qt_sockaddr storage;
    551598    QT_SOCKLEN_T storageSize = sizeof(storage);
     599    memset(&storage, 0, storageSize);
    552600
    553601    // Peek 0 bytes into the next message. The size of the message may
     
    556604    do {
    557605        char c;
    558         readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, storagePtr, &storageSize);
     606        readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize);
    559607    } while (readBytes == -1 && errno == EINTR);
    560608
     
    570618}
    571619
     620#ifdef Q_OS_SYMBIAN
     621qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
     622{
     623    size_t nbytes = 0;
     624    ::ioctl(socketDescriptor, E32IONREAD, (char *) &nbytes);
     625    return qint64(nbytes-28);
     626}
     627#else
    572628qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
    573629{
    574630    QVarLengthArray<char, 8192> udpMessagePeekBuffer(8192);
    575631    ssize_t recvResult = -1;
     632
    576633    for (;;) {
    577634        // the data written to udpMessagePeekBuffer is discarded, so
     
    579636        // so.
    580637        recvResult = ::recv(socketDescriptor, udpMessagePeekBuffer.data(),
    581                             udpMessagePeekBuffer.size(), MSG_PEEK);
     638            udpMessagePeekBuffer.size(), MSG_PEEK);
    582639        if (recvResult == -1 && errno == EINTR)
    583640            continue;
     
    595652    return qint64(recvResult);
    596653}
    597 
     654#endif
    598655qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize,
    599656                                                    QHostAddress *address, quint16 *port)
    600657{
    601 #if !defined(QT_NO_IPV6)
    602     struct sockaddr_storage aa;
    603 #else
    604     struct sockaddr_in aa;
    605 #endif
     658    qt_sockaddr aa;
    606659    memset(&aa, 0, sizeof(aa));
    607660    QT_SOCKLEN_T sz;
     
    612665        char c;
    613666        recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1,
    614                                     0, (struct sockaddr *)&aa, &sz);
     667                                    0, &aa.a, &sz);
    615668    } while (recvFromResult == -1 && errno == EINTR);
    616669
     
    618671        setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
    619672    } else if (port || address) {
    620         qt_socket_getPortAndAddress((struct sockaddr *) &aa, port, address);
     673        qt_socket_getPortAndAddress(&aa, port, address);
    621674    }
    622675
     
    641694    struct sockaddr_in6 sockAddrIPv6;
    642695    if (host.protocol() == QAbstractSocket::IPv6Protocol) {
    643         memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
    644         sockAddrIPv6.sin6_family = AF_INET6;
    645         sockAddrIPv6.sin6_port = htons(port);
    646 
    647         Q_IPV6ADDR tmp = host.toIPv6Address();
    648         memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
    649         sockAddrSize = sizeof(sockAddrIPv6);
    650         sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;
     696    memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
     697    sockAddrIPv6.sin6_family = AF_INET6;
     698    sockAddrIPv6.sin6_port = htons(port);
     699
     700    Q_IPV6ADDR tmp = host.toIPv6Address();
     701    memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
     702    sockAddrSize = sizeof(sockAddrIPv6);
     703    sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;
    651704    } else
    652705#endif
    653706    if (host.protocol() == QAbstractSocket::IPv4Protocol) {
    654         memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
    655         sockAddrIPv4.sin_family = AF_INET;
    656         sockAddrIPv4.sin_port = htons(port);
    657         sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address());
    658         sockAddrSize = sizeof(sockAddrIPv4);
    659         sockAddrPtr = (struct sockaddr *)&sockAddrIPv4;
     707    memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
     708    sockAddrIPv4.sin_family = AF_INET;
     709    sockAddrIPv4.sin_port = htons(port);
     710    sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address());
     711    sockAddrSize = sizeof(sockAddrIPv4);
     712    sockAddrPtr = (struct sockaddr *)&sockAddrIPv4;
    660713    }
    661714
    662715    // ignore the SIGPIPE signal
    663716    qt_ignore_sigpipe();
    664 
    665     ssize_t sentBytes;
    666     do {
    667         sentBytes = ::sendto(socketDescriptor, data, len,
    668                              0, sockAddrPtr, sockAddrSize);
    669     } while (sentBytes == -1 && errno == EINTR);
     717#ifdef Q_OS_SYMBIAN
     718    ssize_t sentBytes = ::sendto(socketDescriptor, data, len,
     719                                       0, sockAddrPtr, sockAddrSize);
     720#else
     721    ssize_t sentBytes = qt_safe_sendto(socketDescriptor, data, len,
     722                                       0, sockAddrPtr, sockAddrSize);
     723#endif
    670724
    671725    if (sentBytes < 0) {
     
    698752        return false;
    699753
    700 #if !defined(QT_NO_IPV6)
    701     struct sockaddr_storage sa;
    702 #else
    703     struct sockaddr_in sa;
    704 #endif
    705     struct sockaddr *sockAddrPtr = (struct sockaddr *) &sa;
     754    qt_sockaddr sa;
    706755    QT_SOCKLEN_T sockAddrSize = sizeof(sa);
    707756
    708757    // Determine local address
    709758    memset(&sa, 0, sizeof(sa));
    710     if (::getsockname(socketDescriptor, sockAddrPtr, &sockAddrSize) == 0) {
    711         qt_socket_getPortAndAddress(sockAddrPtr, &localPort, &localAddress);
     759    if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
     760        qt_socket_getPortAndAddress(&sa, &localPort, &localAddress);
    712761
    713762        // Determine protocol family
    714         switch (sockAddrPtr->sa_family) {
     763        switch (sa.a.sa_family) {
    715764        case AF_INET:
    716765            socketProtocol = QAbstractSocket::IPv4Protocol;
     
    732781
    733782    // Determine the remote address
    734     if (!::getpeername(socketDescriptor, sockAddrPtr, &sockAddrSize))
    735         qt_socket_getPortAndAddress(sockAddrPtr, &peerPort, &peerAddress);
     783    if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize))
     784        qt_socket_getPortAndAddress(&sa, &peerPort, &peerAddress);
    736785
    737786    // Determine the socket type (UDP/TCP)
     
    769818    qDebug("QNativeSocketEngine::nativeClose()");
    770819#endif
     820
     821#ifdef Q_OS_SYMBIAN
    771822    ::close(socketDescriptor);
     823#else
     824        qt_safe_close(socketDescriptor);
     825#endif
    772826}
    773827
     
    783837    ssize_t writtenBytes;
    784838    do {
    785         writtenBytes = ::write(socketDescriptor, data, len);
     839#ifdef Q_OS_SYMBIAN
     840            writtenBytes = ::write(socketDescriptor, data, len);
     841#else
     842        writtenBytes = qt_safe_write(socketDescriptor, data, len);
     843#endif
     844        // writtenBytes = QT_WRITE(socketDescriptor, data, len); ### TODO S60: Should this line be removed or the one above it?
    786845    } while (writtenBytes < 0 && errno == EINTR);
    787846
     
    825884    ssize_t r = 0;
    826885    do {
     886#ifdef Q_OS_SYMBIAN
    827887        r = ::read(socketDescriptor, data, maxSize);
     888#else
     889        r = qt_safe_read(socketDescriptor, data, maxSize);
     890#endif
    828891    } while (r == -1 && errno == EINTR);
    829892
     
    843906            setError(QAbstractSocket::NetworkError, ReadErrorString);
    844907            break;
     908#ifdef Q_OS_SYMBIAN
     909        case EPIPE:
     910#endif
    845911        case ECONNRESET:
     912#if defined(Q_OS_VXWORKS)
     913        case ESHUTDOWN:
     914#endif
    846915            r = 0;
    847916            break;
     
    870939    tv.tv_usec = (timeout % 1000) * 1000;
    871940
    872     QTime timer;
    873     timer.start();
     941#ifdef Q_OS_SYMBIAN
     942    fd_set fdexception;
     943    FD_ZERO(&fdexception);
     944    FD_SET(socketDescriptor, &fdexception);
     945#endif
    874946
    875947    int retval;
    876     do {
    877         if (selectForRead)
    878             retval = select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv);
    879         else
    880             retval = select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv);
    881 
    882         if (retval != -1 || errno != EINTR)
    883             break;
    884 
    885         if (timeout > 0) {
    886             // recalculate the timeout
    887             int t = timeout - timer.elapsed();
    888             if (t < 0) {
    889                 // oops, timeout turned negative?
    890                 retval = -1;
    891                 break;
     948    if (selectForRead)
     949#ifdef Q_OS_SYMBIAN
     950        retval = ::select(socketDescriptor + 1, &fds, 0, &fdexception, timeout < 0 ? 0 : &tv);
     951#else
     952        retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv);
     953#endif
     954    else
     955#ifdef Q_OS_SYMBIAN
     956        retval = ::select(socketDescriptor + 1, 0, &fds, &fdexception, timeout < 0 ? 0 : &tv);
     957#else
     958        retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv);
     959#endif
     960
     961
     962#ifdef Q_OS_SYMBIAN
     963        bool selectForExec = false;
     964        if(retval != 0) {
     965            if(retval < 0) {
     966                qWarning("nativeSelect(....) returned < 0 for socket %d", socketDescriptor);
    892967            }
    893 
    894             tv.tv_sec = t / 1000;
    895             tv.tv_usec = (t % 1000) * 1000;
    896         }
    897     } while (true);
     968            selectForExec = FD_ISSET(socketDescriptor, &fdexception);
     969        }
     970        if(selectForExec) {
     971            qWarning("nativeSelect (selectForRead %d, retVal %d, errno %d) Unexpected exception for fd %d",
     972                    selectForRead, retval, errno, socketDescriptor);
     973            }
     974#endif
    898975
    899976    return retval;
     
    901978
    902979int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
    903                                       bool *selectForRead, bool *selectForWrite) const
     980                       bool *selectForRead, bool *selectForWrite) const
    904981{
    905982    fd_set fdread;
     
    913990        FD_SET(socketDescriptor, &fdwrite);
    914991
     992#ifdef Q_OS_SYMBIAN
     993    fd_set fdexception;
     994    FD_ZERO(&fdexception);
     995    FD_SET(socketDescriptor, &fdexception);
     996#endif
     997
    915998    struct timeval tv;
    916999    tv.tv_sec = timeout / 1000;
    9171000    tv.tv_usec = (timeout % 1000) * 1000;
    9181001
     1002    int ret;
     1003#ifndef Q_OS_SYMBIAN
     1004    ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
     1005#else
    9191006    QTime timer;
    9201007    timer.start();
    9211008
    922     int ret;
    9231009    do {
    924         ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
    925         if (ret != -1 || errno != EINTR)
    926             break;
     1010        ret = ::select(socketDescriptor + 1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv);
     1011        bool selectForExec = false;
     1012        if(ret != 0) {
     1013            if(ret < 0) {
     1014                qWarning("nativeSelect(....) returned < 0 for socket %d", socketDescriptor);
     1015            }
     1016            selectForExec = FD_ISSET(socketDescriptor, &fdexception);
     1017        }
     1018        if(selectForExec) {
     1019            qWarning("nativeSelect (checkRead %d, checkWrite %d, ret %d, errno %d): Unexpected expectfds ready in fd %d",
     1020                    checkRead, checkWrite, ret, errno, socketDescriptor);
     1021            if (checkWrite){
     1022                FD_CLR(socketDescriptor, &fdread);
     1023                FD_SET(socketDescriptor, &fdwrite);
     1024            } else if (checkRead)
     1025                FD_SET(socketDescriptor, &fdread);
     1026
     1027
     1028            if ((ret == -1) && ( errno == ECONNREFUSED || errno == EPIPE ))
     1029                ret = 1;
     1030
     1031        }
     1032
     1033        if (ret != -1 || errno != EINTR) {
     1034            break;
     1035        }
    9271036
    9281037        if (timeout > 0) {
     
    9391048        }
    9401049    } while (true);
     1050#endif
     1051
    9411052    if (ret <= 0)
    9421053        return ret;
    943 
    9441054    *selectForRead = FD_ISSET(socketDescriptor, &fdread);
    9451055    *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);
     1056
    9461057    return ret;
    9471058}
  • trunk/src/network/socket/qnativesocketengine_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    150150#endif
    151151
    152 #if !defined (QT_NO_IPV6)
    153 
    154 // Use our own defines and structs which we know are correct
    155 #  define QT_SS_MAXSIZE 128
    156 #  define QT_SS_ALIGNSIZE (sizeof(__int64))
    157 #  define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short))
    158 #  define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE))
    159 struct qt_sockaddr_storage {
    160       short ss_family;
    161       char __ss_pad1[QT_SS_PAD1SIZE];
    162       __int64 __ss_align;
    163       char __ss_pad2[QT_SS_PAD2SIZE];
    164 };
    165 
    166 // sockaddr_in6 size changed between old and new SDK
    167 // Only the new version is the correct one, so always
    168 // use this structure.
    169 struct qt_in6_addr {
    170     u_char qt_s6_addr[16];
    171 };
    172 typedef struct {
    173     short   sin6_family;            /* AF_INET6 */
    174     u_short sin6_port;              /* Transport level port number */
    175     u_long  sin6_flowinfo;          /* IPv6 flow information */
    176     struct  qt_in6_addr sin6_addr;  /* IPv6 address */
    177     u_long  sin6_scope_id;          /* set of interfaces for a scope */
    178 } qt_sockaddr_in6;
    179 
    180 #else
    181 
    182 typedef void * qt_sockaddr_in6 ;
    183 
    184 
    185 #endif
    186 
    187152#ifndef AF_INET6
    188153#define AF_INET6        23              /* Internetwork Version 6 */
     
    202167    \a port and \a addr if they are non-null.
    203168*/
    204 static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, struct sockaddr *sa, quint16 *port, QHostAddress *address)
     169static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt_sockaddr *sa, quint16 *port, QHostAddress *address)
    205170{
    206171#if !defined (QT_NO_IPV6)
    207     if (sa->sa_family == AF_INET6) {
    208         qt_sockaddr_in6 *sa6 = (qt_sockaddr_in6 *)sa;
     172    if (sa->a.sa_family == AF_INET6) {
     173        const qt_sockaddr_in6 *sa6 = &sa->a6;
    209174        Q_IPV6ADDR tmp;
    210175        for (int i = 0; i < 16; ++i)
     
    218183    } else
    219184#endif
    220     if (sa->sa_family == AF_INET) {
    221         struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
     185    if (sa->a.sa_family == AF_INET) {
     186        const sockaddr_in *sa4 = &sa->a4;
    222187        unsigned long addr;
    223188        WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr);
     
    398363
    399364    int n = -1;
     365    int level = SOL_SOCKET; // default
     366
    400367    switch (opt) {
    401368    case QNativeSocketEngine::ReceiveBufferSocketOption:
     
    425392        n = SO_OOBINLINE;
    426393        break;
     394    case QNativeSocketEngine::LowDelayOption:
     395        level = IPPROTO_TCP;
     396        n = TCP_NODELAY;
     397        break;
     398    case QNativeSocketEngine::KeepAliveOption:
     399        n = SO_KEEPALIVE;
     400        break;
    427401    }
    428402
    429403    int v = -1;
    430404    QT_SOCKOPTLEN_T len = sizeof(v);
    431     if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)
     405    if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
    432406        return v;
    433407    return -1;
     
    445419
    446420    int n = 0;
     421    int level = SOL_SOCKET; // default
     422
    447423    switch (opt) {
    448424    case QNativeSocketEngine::ReceiveBufferSocketOption:
     
    476452        n = SO_OOBINLINE;
    477453        break;
    478     }
    479 
    480     if (::setsockopt(socketDescriptor, SOL_SOCKET, n, (char*)&v, sizeof(v)) != 0) {
     454    case QNativeSocketEngine::LowDelayOption:
     455        level = IPPROTO_TCP;
     456        n = TCP_NODELAY;
     457        break;
     458    case QNativeSocketEngine::KeepAliveOption:
     459        n = SO_KEEPALIVE;
     460        break;
     461    }
     462
     463    if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
    481464        WS_ERROR_DEBUG(WSAGetLastError());
    482465        return false;
     
    499482       return false;
    500483
    501 #if !defined (QT_NO_IPV6)
    502     struct qt_sockaddr_storage sa;
    503 #else
    504     struct sockaddr_in sa;
    505 #endif
    506     struct sockaddr *pSa = (struct sockaddr *) &sa;
    507 
    508     QT_SOCKLEN_T sz = sizeof(sa);
    509 
     484    qt_sockaddr sa;
     485    QT_SOCKLEN_T sockAddrSize = sizeof(sa);
     486
     487    // Determine local address
    510488    memset(&sa, 0, sizeof(sa));
    511     if (::getsockname(socketDescriptor, pSa, &sz) == 0) {
    512         qt_socket_getPortAndAddress(socketDescriptor, pSa, &localPort, &localAddress);
     489    if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
     490        qt_socket_getPortAndAddress(socketDescriptor, &sa, &localPort, &localAddress);
    513491        // Determine protocol family
    514         switch (pSa->sa_family) {
     492        switch (sa.a.sa_family) {
    515493        case AF_INET:
    516494            socketProtocol = QAbstractSocket::IPv4Protocol;
     
    536514
    537515    memset(&sa, 0, sizeof(sa));
    538     if (::getpeername(socketDescriptor, pSa, &sz) == 0) {
    539         qt_socket_getPortAndAddress(socketDescriptor, pSa, &peerPort, &peerAddress);
     516    if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
     517        qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
    540518    } else {
    541519        WS_ERROR_DEBUG(WSAGetLastError());
     
    569547    struct sockaddr_in sockAddrIPv4;
    570548    qt_sockaddr_in6 sockAddrIPv6;
    571     struct sockaddr *sockAddrPtr;
    572     QT_SOCKLEN_T sockAddrSize;
     549    struct sockaddr *sockAddrPtr = 0;
     550    QT_SOCKLEN_T sockAddrSize = 0;
    573551
    574552    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
     
    606584                        break;
    607585                    }
     586                    if (value == WSAEHOSTUNREACH) {
     587                        setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
     588                        socketState = QAbstractSocket::UnconnectedState;
     589                        break;
     590                    }
    608591                }
    609592                // fall through
     
    669652    struct sockaddr_in sockAddrIPv4;
    670653    qt_sockaddr_in6 sockAddrIPv6;
    671     struct sockaddr *sockAddrPtr;
    672     QT_SOCKLEN_T sockAddrSize;
     654    struct sockaddr *sockAddrPtr = 0;
     655    QT_SOCKLEN_T sockAddrSize = 0;
    673656
    674657    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
     
    797780#if !defined(Q_OS_WINCE)
    798781    // Create a sockaddr struct and reset its port number.
    799 #if !defined(QT_NO_IPV6)
    800     qt_sockaddr_in6 storage;
    801     qt_sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<qt_sockaddr_in6 *>(&storage);
    802     storagePtrIPv6->sin6_port = 0;
    803 #else
    804     struct sockaddr storage;
    805 #endif
    806     sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage);
    807     storagePtr->sa_family = 0;
    808 
    809     sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage);
    810     storagePtrIPv4->sin_port = 0;
     782    qt_sockaddr storage;
    811783    QT_SOCKLEN_T storageSize = sizeof(storage);
    812 
     784    memset(&storage, 0, storageSize);
    813785
    814786    bool result = false;
     
    822794    DWORD available = 0;
    823795    DWORD flags = MSG_PEEK;
    824     int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, storagePtr, &storageSize,0,0);
     796    int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, &storage.a, &storageSize,0,0);
    825797    int err = WSAGetLastError();
    826798    if (ret == SOCKET_ERROR && err !=  WSAEMSGSIZE) {
     
    832804            flags = 0;
    833805            ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags,
    834                           storagePtr, &storageSize, 0, 0);
     806                          &storage.a, &storageSize, 0, 0);
    835807        }
    836808    } else {
     
    924896    qint64 ret = 0;
    925897
    926 #if !defined(QT_NO_IPV6)
    927     qt_sockaddr_storage aa;
    928 #else
    929     struct sockaddr_in aa;
    930 #endif
     898    qt_sockaddr aa;
    931899    memset(&aa, 0, sizeof(aa));
    932900    QT_SOCKLEN_T sz;
    933901    sz = sizeof(aa);
     902
    934903    WSABUF buf;
    935904    buf.buf = data;
     
    946915    DWORD flags = 0;
    947916    DWORD bytesRead = 0;
    948     int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, (struct sockaddr *) &aa, &sz,0,0);
     917    int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, &aa.a, &sz,0,0);
    949918    if (wsaRet == SOCKET_ERROR) {
    950919        int err = WSAGetLastError();
    951920        if (err == WSAEMSGSIZE) {
    952921            // it is ok the buffer was to small if bytesRead is larger than
    953             // maxLength (win 9x) then assume bytes read is really maxLenth
     922            // maxLength then assume bytes read is really maxLenth
    954923            ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead);
    955924        } else {
     
    962931    }
    963932
    964     qt_socket_getPortAndAddress(socketDescriptor, (struct sockaddr *) &aa, port, address);
     933    qt_socket_getPortAndAddress(socketDescriptor, &aa, port, address);
    965934
    966935#if defined (QNATIVESOCKETENGINE_DEBUG)
     
    981950    struct sockaddr_in sockAddrIPv4;
    982951    qt_sockaddr_in6 sockAddrIPv6;
    983     struct sockaddr *sockAddrPtr;
    984     QT_SOCKLEN_T sockAddrSize;
     952    struct sockaddr *sockAddrPtr = 0;
     953    QT_SOCKLEN_T sockAddrSize = 0;
    985954
    986955    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
    987956
    988     if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && len > qint64(qt_socket_getMaxMsgSize(socketDescriptor))) {
    989         // WSAEMSGSIZE is not reliable enough (win 9x) so we check max size our self.
    990         setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
     957    WSABUF buf;
     958#if !defined(Q_OS_WINCE)
     959    buf.buf = len ? (char*)data : 0;
     960#else
     961    char tmp;
     962    buf.buf = len ? (char*)data : &tmp;
     963#endif
     964    buf.len = len;
     965    DWORD flags = 0;
     966    DWORD bytesSent = 0;
     967    if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) ==  SOCKET_ERROR) {
     968        int err = WSAGetLastError();
     969        WS_ERROR_DEBUG(err);
     970        switch (err) {
     971        case WSAEMSGSIZE:
     972            setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
     973            break;
     974        default:
     975            setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
     976            break;
     977        }
     978        ret = -1;
    991979    } else {
    992         WSABUF buf;
    993 #if !defined(Q_OS_WINCE)
    994         buf.buf = len ? (char*)data : 0;
    995 #else
    996         char tmp;
    997         buf.buf = len ? (char*)data : &tmp;
    998 #endif
    999         buf.len = len;
    1000         DWORD flags = 0;
    1001         DWORD bytesSent = 0;
    1002         if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) ==  SOCKET_ERROR) {
    1003             int err = WSAGetLastError();
    1004             WS_ERROR_DEBUG(err);
    1005             switch (err) {
    1006             case WSAEMSGSIZE:
    1007                 setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
    1008                 break;
    1009             default:
    1010                 setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
    1011                 break;
    1012             }
    1013             ret = -1;
    1014         } else {
    1015             ret = qint64(bytesSent);
    1016         }
    1017     }
     980        ret = qint64(bytesSent);
     981    }
     982
    1018983#if defined (QNATIVESOCKETENGINE_DEBUG)
    1019984    qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data,
     
    11431108    tv.tv_usec = (timeout % 1000) * 1000;
    11441109
    1145     if (selectForRead)
     1110    if (selectForRead) {
    11461111        ret = select(0, &fds, 0, 0, timeout < 0 ? 0 : &tv);
    1147     else
    1148         ret = select(0, 0, &fds, 0, timeout < 0 ? 0 : &tv);
     1112    } else {
     1113        // select for write
     1114
     1115        // Windows needs this to report errors when connecting a socket ...
     1116        fd_set fdexception;
     1117        FD_ZERO(&fdexception);
     1118        FD_SET(socketDescriptor, &fdexception);
     1119
     1120        ret = select(0, 0, &fds, &fdexception, timeout < 0 ? 0 : &tv);
     1121
     1122        // ... but if it is actually set, pretend it did not happen
     1123        if (ret > 0 && FD_ISSET(socketDescriptor, &fdexception))
     1124            ret--;
     1125    }
    11491126
    11501127    if (readEnabled)
     
    11611138    if (readEnabled)
    11621139        readNotifier->setEnabled(false);
    1163    
     1140
    11641141    fd_set fdread;
    11651142    fd_set fdwrite;
     1143    fd_set fdexception;
    11661144
    11671145    int ret = 0;
     
    11731151    }
    11741152    memset(&fdwrite, 0, sizeof(fd_set));
     1153    FD_ZERO(&fdexception);
    11751154    if (checkWrite) {
    11761155        fdwrite.fd_count = 1;
    11771156        fdwrite.fd_array[0] = socketDescriptor;
     1157
     1158        // Windows needs this to report errors when connecting a socket
     1159        FD_SET(socketDescriptor, &fdexception);
    11781160    }
    11791161
     
    11831165
    11841166#if !defined(Q_OS_WINCE)
    1185     ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
     1167    ret = select(socketDescriptor + 1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv);
    11861168#else
    1187     ret = select(1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
    1188 #endif
     1169    ret = select(1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv);
     1170#endif
     1171
     1172     //... but if it is actually set, pretend it did not happen
     1173    if (ret > 0 && FD_ISSET(socketDescriptor, &fdexception))
     1174        ret--;
     1175
    11891176    if (readEnabled)
    11901177        readNotifier->setEnabled(true);
  • trunk/src/network/socket/qsocks5socketengine.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060QT_BEGIN_NAMESPACE
    6161
     62#ifdef Q_OS_SYMBIAN
     63static const int MaxWriteBufferSize = 4*1024;
     64#else
    6265static const int MaxWriteBufferSize = 128*1024;
     66#endif
    6367
    6468//#define QSOCKS5SOCKETLAYER_DEBUG
     
    154158static bool qt_socks5_set_host_address_and_port(const QHostAddress &address, quint16 port, QByteArray *pBuf)
    155159{
    156     QSOCKS5_DEBUG << "setting [" << address << ":" << port << "]";
     160    QSOCKS5_DEBUG << "setting [" << address << ':' << port << ']';
    157161
    158162    union {
     
    187191static bool qt_socks5_set_host_name_and_port(const QString &hostname, quint16 port, QByteArray *pBuf)
    188192{
    189     QSOCKS5_DEBUG << "setting [" << hostname << ":" << port << "]";
     193    QSOCKS5_DEBUG << "setting [" << hostname << ':' << port << ']';
    190194
    191195    QByteArray encodedHostName = QUrl::toAce(hostname);
     
    266270
    267271    if (ret) {
    268         QSOCKS5_DEBUG << "got [" << address << ":" << port << "]";
     272        QSOCKS5_DEBUG << "got [" << address << ':' << port << ']';
    269273        *pAddress = address;
    270274        *pPort = port;
     
    11251129{
    11261130    Q_D(QSocks5SocketEngine);
    1127     QSOCKS5_DEBUG << "connectToHost" << address << ":" << port;
     1131    QSOCKS5_DEBUG << "connectToHost" << address << ':' << port;
    11281132
    11291133    setPeerAddress(address);
     
    12321236            connectData->readBuffer.clear();
    12331237        emitReadNotification();
     1238        data->controlSocket->close();
     1239        // cause a disconnect in the outer socket
     1240        emitWriteNotification();
    12341241    } else if (socks5State == Uninitialized
    12351242               || socks5State == AuthenticationMethodsSent
     
    12421249        q_func()->setError(data->controlSocket->error(), data->controlSocket->errorString());
    12431250        emitReadNotification();
     1251        emitWriteNotification();
    12441252    }
    12451253}
     
    13801388            return false;
    13811389        }
    1382         QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ":" << d->localPort;
     1390        QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ':' << d->localPort;
    13831391        return true;
    13841392#endif // QT_NO_UDPSOCKET
     
    14791487{
    14801488    Q_D(QSocks5SocketEngine);
    1481     QSOCKS5_Q_DEBUG << "read( , maxlen = " << maxlen << ")";
     1489    QSOCKS5_Q_DEBUG << "read( , maxlen = " << maxlen << ')';
    14821490    if (d->mode == QSocks5SocketEnginePrivate::ConnectMode) {
    14831491        if (d->connectData->readBuffer.size() == 0) {
     
    16201628#endif // QT_NO_UDPSOCKET
    16211629
     1630qint64 QSocks5SocketEngine::bytesToWrite() const
     1631{
     1632    Q_D(const QSocks5SocketEngine);
     1633    if (d->data && d->data->controlSocket) {
     1634        return d->data->controlSocket->bytesToWrite();
     1635    } else {
     1636        return 0;
     1637    }
     1638}
     1639
    16221640int QSocks5SocketEngine::option(SocketOption option) const
    16231641{
    1624     Q_UNUSED(option);
     1642    Q_D(const QSocks5SocketEngine);
     1643    if (d->data && d->data->controlSocket) {
     1644        // convert the enum and call the real socket
     1645        if (option == QAbstractSocketEngine::LowDelayOption)
     1646            return d->data->controlSocket->socketOption(QAbstractSocket::LowDelayOption).toInt();
     1647        if (option == QAbstractSocketEngine::KeepAliveOption)
     1648            return d->data->controlSocket->socketOption(QAbstractSocket::KeepAliveOption).toInt();
     1649    }
    16251650    return -1;
    16261651}
     
    16281653bool QSocks5SocketEngine::setOption(SocketOption option, int value)
    16291654{
    1630     Q_UNUSED(option);
    1631     Q_UNUSED(value);
     1655    Q_D(QSocks5SocketEngine);
     1656    if (d->data && d->data->controlSocket) {
     1657        // convert the enum and call the real socket
     1658        if (option == QAbstractSocketEngine::LowDelayOption)
     1659            d->data->controlSocket->setSocketOption(QAbstractSocket::LowDelayOption, value);
     1660        if (option == QAbstractSocketEngine::KeepAliveOption)
     1661            d->data->controlSocket->setSocketOption(QAbstractSocket::KeepAliveOption, value);
     1662        return true;
     1663    }
    16321664    return false;
    16331665}
     
    17671799    Q_D(QSocks5SocketEngine);
    17681800
    1769     QSOCKS5_Q_DEBUG << "setReadNotificationEnabled(" << enable << ")";
     1801    QSOCKS5_Q_DEBUG << "setReadNotificationEnabled(" << enable << ')';
    17701802
    17711803    bool emitSignal = false;
     
    18311863        return 0;
    18321864    }
    1833     QSocks5SocketEngine *engine = new QSocks5SocketEngine(parent);
     1865    QScopedPointer<QSocks5SocketEngine> engine(new QSocks5SocketEngine(parent));
    18341866    engine->setProxy(proxy);
    1835     return engine;
     1867    return engine.take();
    18361868}
    18371869
  • trunk/src/network/socket/qsocks5socketengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    100100    qint64 pendingDatagramSize() const;
    101101#endif // QT_NO_UDPSOCKET
     102
     103    qint64 bytesToWrite() const;
    102104
    103105    int option(SocketOption option) const;
  • trunk/src/network/socket/qtcpserver.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4747
    4848    \reentrant
    49     \ingroup io
     49    \ingroup network
    5050    \inmodule QtNetwork
    5151
     
    355355    if (d->socketEngine) {
    356356        d->socketEngine->close();
    357         d->socketEngine->deleteLater();
     357        QT_TRY {
     358            d->socketEngine->deleteLater();
     359        } QT_CATCH(const std::bad_alloc &) {
     360            // in out of memory situations, the socketEngine
     361            // will be deleted in ~QTcpServer (it's a child-object of this)
     362        }
    358363        d->socketEngine = 0;
    359364    }
  • trunk/src/network/socket/qtcpserver.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/network/socket/qtcpsocket.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848
    4949    \reentrant
    50     \ingroup io
     50    \ingroup network
    5151    \inmodule QtNetwork
    5252
     
    6161    \bold{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode.
    6262
    63     \sa QTcpServer, QUdpSocket, QFtp, QHttp, {Fortune Server Example},
    64         {Fortune Client Example}, {Threaded Fortune Server Example},
    65         {Blocking Fortune Client Example}, {Loopback Example},
    66         {Torrent Example}
     63    \sa QTcpServer, QUdpSocket, QFtp, QNetworkAccessManager,
     64    {Fortune Server Example}, {Fortune Client Example},
     65    {Threaded Fortune Server Example}, {Blocking Fortune Client Example},
     66    {Loopback Example}, {Torrent Example}
    6767*/
    6868
  • trunk/src/network/socket/qtcpsocket.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444
    4545#include <QtNetwork/qabstractsocket.h>
     46#include <QtCore/qvariant.h>
    4647
    4748QT_BEGIN_HEADER
  • trunk/src/network/socket/qtcpsocket_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/network/socket/qudpsocket.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4747    \brief The QUdpSocket class provides a UDP socket.
    4848
    49     \ingroup io
     49    \ingroup network
    5050    \inmodule QtNetwork
    5151
     
    7171    datagram, and readDatagram() to read it.
    7272
     73    \note An incoming datagram should be read when you receive the readyRead()
     74    signal, otherwise this signal will not be emitted for the next datagram.
     75
    7376    Example:
    7477
     
    9295    This enum describes the different flags you can pass to modify the
    9396    behavior of QUdpSocket::bind().
     97
     98    \note On Symbian OS bind flags behaviour depends on process capabilties.
     99    If process has NetworkControl capability, the bind attempt with
     100    ReuseAddressHint will always succeed even if the address and port is already
     101    bound by another socket with any flags. If process does not have
     102    NetworkControl capability, the bind attempt to address and port already
     103    bound by another socket will always fail.
    94104
    95105    \value ShareAddress Allow other services to bind to the same address
     
    348358    destination.
    349359
     360    \warning In S60 5.0 and earlier versions, the writeDatagram return
     361    value is not reliable for large datagrams.
     362
    350363    \warning Calling this function on a connected UDP socket may
    351364    result in an error and no packet being sent. If you are using a
     
    366379
    367380    qint64 sent = d->socketEngine->writeDatagram(data, size, address, port);
     381#ifdef Q_OS_SYMBIAN
     382    if( QSysInfo::s60Version() <= QSysInfo::SV_S60_5_0 ) {
     383        // This is evil hack, but for some reason native RSocket::SendTo returns 0,
     384        // for large datagrams (such as 600 bytes). Based on comments from Open C team
     385        // this should happen only in platforms <= S60 5.0.
     386        // As an workaround, we just set sent = size
     387        if( sent == 0 )
     388            sent = size;
     389    }
     390#endif
    368391    d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
    369392
     
    378401}
    379402
    380 /*! 
     403/*!
    381404    \fn qint64 QUdpSocket::writeDatagram(const QByteArray &datagram,
    382405                                             const QHostAddress &host, quint16 port)
  • trunk/src/network/socket/qudpsocket.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/network/socket/socket.pri

    r157 r561  
    2929                socket/qlocalsocket_unix.cpp \
    3030                socket/qlocalserver_unix.cpp
    31 
     31unix:HEADERS += \
     32                socket/qnet_unix_p.h
    3233
    3334win32:SOURCES += socket/qnativesocketengine_win.cpp \
     
    4748    DEFINES += QT_LOCALSOCKET_TCP
    4849}
    49 
    50 
Note: See TracChangeset for help on using the changeset viewer.