PageRenderTime 102ms CodeModel.GetById 7ms app.highlight 82ms RepoModel.GetById 1ms app.codeStats 1ms

/src/common/socket.cpp

https://github.com/jay/wxWidgets
C++ | 2170 lines | 1409 code | 435 blank | 326 comment | 257 complexity | 98704a70ce9062ddb44c2f4b17fa9a0b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/////////////////////////////////////////////////////////////////////////////
   2// Name:       src/common/socket.cpp
   3// Purpose:    Socket handler classes
   4// Authors:    Guilhem Lavaux, Guillermo Rodriguez Garcia
   5// Created:    April 1997
   6// Copyright:  (C) 1999-1997, Guilhem Lavaux
   7//             (C) 1999-2000, Guillermo Rodriguez Garcia
   8//             (C) 2008 Vadim Zeitlin
   9// Licence:    wxWindows licence
  10/////////////////////////////////////////////////////////////////////////////
  11
  12// ==========================================================================
  13// Declarations
  14// ==========================================================================
  15
  16// For compilers that support precompilation, includes "wx.h".
  17#include "wx/wxprec.h"
  18
  19#ifdef __BORLANDC__
  20    #pragma hdrstop
  21#endif
  22
  23#if wxUSE_SOCKETS
  24
  25#include "wx/socket.h"
  26
  27#ifndef WX_PRECOMP
  28    #include "wx/object.h"
  29    #include "wx/string.h"
  30    #include "wx/intl.h"
  31    #include "wx/log.h"
  32    #include "wx/event.h"
  33    #include "wx/app.h"
  34    #include "wx/utils.h"
  35    #include "wx/timer.h"
  36    #include "wx/module.h"
  37    #include "wx/filefn.h"
  38#endif
  39
  40#include "wx/apptrait.h"
  41#include "wx/sckaddr.h"
  42#include "wx/scopeguard.h"
  43#include "wx/stopwatch.h"
  44#include "wx/thread.h"
  45#include "wx/evtloop.h"
  46#include "wx/link.h"
  47
  48#include "wx/private/fd.h"
  49#include "wx/private/socket.h"
  50
  51#ifdef __UNIX__
  52    #include <errno.h>
  53#endif
  54
  55// we use MSG_NOSIGNAL to avoid getting SIGPIPE when sending data to a remote
  56// host which closed the connection if it is available, otherwise we rely on
  57// SO_NOSIGPIPE existency
  58//
  59// this should cover all the current Unix systems (Windows never sends any
  60// signals anyhow) but if we find one that has neither we should explicitly
  61// ignore SIGPIPE for it
  62// OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample
  63// seems to work. Not sure if problems will show up on OpenVMS using sockets.
  64#ifdef MSG_NOSIGNAL
  65    #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
  66#else // MSG_NOSIGNAL not available (BSD including OS X)
  67    // next best possibility is to use SO_NOSIGPIPE socket option, this covers
  68    // BSD systems (including OS X) -- but if we don't have it neither (AIX and
  69    // old HP-UX do not), we have to fall back to the old way of simply
  70    // disabling SIGPIPE temporarily, so define a class to do it in a safe way
  71    #if defined(__UNIX__) && !defined(SO_NOSIGPIPE)
  72    extern "C" { typedef void (*wxSigHandler_t)(int); }
  73    namespace
  74    {
  75        class IgnoreSignal
  76        {
  77        public:
  78            // ctor disables the given signal
  79            IgnoreSignal(int sig)
  80                : m_handler(signal(sig, SIG_IGN)),
  81                  m_sig(sig)
  82            {
  83            }
  84
  85            // dtor restores the old handler
  86            ~IgnoreSignal()
  87            {
  88                signal(m_sig, m_handler);
  89            }
  90
  91        private:
  92            const wxSigHandler_t m_handler;
  93            const int m_sig;
  94
  95            wxDECLARE_NO_COPY_CLASS(IgnoreSignal);
  96        };
  97    } // anonymous namespace
  98
  99    #define wxNEEDS_IGNORE_SIGPIPE
 100    #endif // Unix without SO_NOSIGPIPE
 101
 102    #define wxSOCKET_MSG_NOSIGNAL 0
 103#endif
 104
 105// DLL options compatibility check:
 106#include "wx/build.h"
 107WX_CHECK_BUILD_OPTIONS("wxNet")
 108
 109// --------------------------------------------------------------------------
 110// macros and constants
 111// --------------------------------------------------------------------------
 112
 113// event
 114wxDEFINE_EVENT(wxEVT_SOCKET, wxSocketEvent);
 115
 116// discard buffer
 117#define MAX_DISCARD_SIZE (10 * 1024)
 118
 119#define wxTRACE_Socket wxT("wxSocket")
 120
 121// --------------------------------------------------------------------------
 122// wxWin macros
 123// --------------------------------------------------------------------------
 124
 125IMPLEMENT_CLASS(wxSocketBase, wxObject)
 126IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
 127IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
 128IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
 129IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
 130
 131// ----------------------------------------------------------------------------
 132// private functions
 133// ----------------------------------------------------------------------------
 134
 135namespace
 136{
 137
 138void SetTimeValFromMS(timeval& tv, unsigned long ms)
 139{
 140    tv.tv_sec  = (ms / 1000);
 141    tv.tv_usec = (ms % 1000) * 1000;
 142}
 143
 144} // anonymous namespace
 145
 146// --------------------------------------------------------------------------
 147// private classes
 148// --------------------------------------------------------------------------
 149
 150class wxSocketState : public wxObject
 151{
 152public:
 153    wxSocketFlags            m_flags;
 154    wxSocketEventFlags       m_eventmask;
 155    bool                     m_notify;
 156    void                    *m_clientData;
 157
 158public:
 159    wxSocketState() : wxObject() {}
 160
 161    wxDECLARE_NO_COPY_CLASS(wxSocketState);
 162};
 163
 164// wxSocketWaitModeChanger: temporarily change the socket flags affecting its
 165// wait mode
 166class wxSocketWaitModeChanger
 167{
 168public:
 169    // temporarily set the flags to include the flag value which may be either
 170    // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
 171    wxSocketWaitModeChanger(wxSocketBase *socket, int flag)
 172        : m_socket(socket),
 173          m_oldflags(socket->GetFlags())
 174
 175    {
 176        // We can be passed only wxSOCKET_WAITALL{_READ,_WRITE} or
 177        // wxSOCKET_NOWAIT{_READ,_WRITE} normally.
 178        wxASSERT_MSG( !(flag & wxSOCKET_WAITALL) || !(flag & wxSOCKET_NOWAIT),
 179                      "not a wait flag" );
 180
 181        // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
 182        // mode but not when switching to wxSOCKET_NOWAIT as the latter is
 183        // incompatible with wxSOCKET_BLOCK
 184        if ( flag != wxSOCKET_NOWAIT )
 185            flag |= m_oldflags & wxSOCKET_BLOCK;
 186
 187        socket->SetFlags(flag);
 188    }
 189
 190    ~wxSocketWaitModeChanger()
 191    {
 192        m_socket->SetFlags(m_oldflags);
 193    }
 194
 195private:
 196    wxSocketBase * const m_socket;
 197    const int m_oldflags;
 198
 199    wxDECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger);
 200};
 201
 202// wxSocketRead/WriteGuard are instantiated before starting reading
 203// from/writing to the socket
 204class wxSocketReadGuard
 205{
 206public:
 207    wxSocketReadGuard(wxSocketBase *socket)
 208        : m_socket(socket)
 209    {
 210        wxASSERT_MSG( !m_socket->m_reading, "read reentrancy?" );
 211
 212        m_socket->m_reading = true;
 213    }
 214
 215    ~wxSocketReadGuard()
 216    {
 217        m_socket->m_reading = false;
 218
 219        // connection could have been lost while reading, in this case calling
 220        // ReenableEvents() would assert and is not necessary anyhow
 221        wxSocketImpl * const impl = m_socket->m_impl;
 222        if ( impl && impl->m_fd != INVALID_SOCKET )
 223            impl->ReenableEvents(wxSOCKET_INPUT_FLAG);
 224    }
 225
 226private:
 227    wxSocketBase * const m_socket;
 228
 229    wxDECLARE_NO_COPY_CLASS(wxSocketReadGuard);
 230};
 231
 232class wxSocketWriteGuard
 233{
 234public:
 235    wxSocketWriteGuard(wxSocketBase *socket)
 236        : m_socket(socket)
 237    {
 238        wxASSERT_MSG( !m_socket->m_writing, "write reentrancy?" );
 239
 240        m_socket->m_writing = true;
 241    }
 242
 243    ~wxSocketWriteGuard()
 244    {
 245        m_socket->m_writing = false;
 246
 247        wxSocketImpl * const impl = m_socket->m_impl;
 248        if ( impl && impl->m_fd != INVALID_SOCKET )
 249            impl->ReenableEvents(wxSOCKET_OUTPUT_FLAG);
 250    }
 251
 252private:
 253    wxSocketBase * const m_socket;
 254
 255    wxDECLARE_NO_COPY_CLASS(wxSocketWriteGuard);
 256};
 257
 258// ============================================================================
 259// wxSocketManager
 260// ============================================================================
 261
 262wxSocketManager *wxSocketManager::ms_manager = NULL;
 263
 264/* static */
 265void wxSocketManager::Set(wxSocketManager *manager)
 266{
 267    wxASSERT_MSG( !ms_manager, "too late to set manager now" );
 268
 269    ms_manager = manager;
 270}
 271
 272/* static */
 273void wxSocketManager::Init()
 274{
 275    wxASSERT_MSG( !ms_manager, "shouldn't be initialized twice" );
 276
 277    /*
 278        Details: Initialize() creates a hidden window as a sink for socket
 279        events, such as 'read completed'. wxMSW has only one message loop
 280        for the main thread. If Initialize is called in a secondary thread,
 281        the socket window will be created for the secondary thread, but
 282        since there is no message loop on this thread, it will never
 283        receive events and all socket operations will time out.
 284        BTW, the main thread must not be stopped using sleep or block
 285        on a semaphore (a bad idea in any case) or socket operations
 286        will time out.
 287
 288        On the Mac side, Initialize() stores a pointer to the CFRunLoop for
 289        the main thread. Because secondary threads do not have run loops,
 290        adding event notifications to the "Current" loop would have no
 291        effect at all, events would never fire.
 292    */
 293    wxASSERT_MSG( wxIsMainThread(),
 294                    "sockets must be initialized from the main thread" );
 295
 296    wxAppConsole * const app = wxAppConsole::GetInstance();
 297    wxCHECK_RET( app, "sockets can't be initialized without wxApp" );
 298
 299    ms_manager = app->GetTraits()->GetSocketManager();
 300}
 301
 302// ==========================================================================
 303// wxSocketImpl
 304// ==========================================================================
 305
 306wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
 307    : m_wxsocket(&wxsocket)
 308{
 309    m_fd              = INVALID_SOCKET;
 310    m_error           = wxSOCKET_NOERROR;
 311    m_server          = false;
 312    m_stream          = true;
 313
 314    SetTimeout(wxsocket.GetTimeout() * 1000);
 315
 316    m_establishing    = false;
 317    m_reusable        = false;
 318    m_broadcast       = false;
 319    m_dobind          = true;
 320    m_initialRecvBufferSize = -1;
 321    m_initialSendBufferSize = -1;
 322}
 323
 324wxSocketImpl::~wxSocketImpl()
 325{
 326    if ( m_fd != INVALID_SOCKET )
 327        Shutdown();
 328}
 329
 330bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl& addr)
 331{
 332    if ( m_fd != INVALID_SOCKET )
 333    {
 334        m_error = wxSOCKET_INVSOCK;
 335        return false;
 336    }
 337
 338    if ( !addr.IsOk() )
 339    {
 340        m_error = wxSOCKET_INVADDR;
 341        return false;
 342    }
 343
 344    return true;
 345}
 346
 347void wxSocketImpl::PostCreation()
 348{
 349    // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
 350#ifdef SO_NOSIGPIPE
 351    EnableSocketOption(SO_NOSIGPIPE);
 352#endif
 353
 354    if ( m_reusable )
 355        EnableSocketOption(SO_REUSEADDR);
 356
 357    if ( m_broadcast )
 358    {
 359        wxASSERT_MSG( !m_stream, "broadcasting is for datagram sockets only" );
 360
 361        EnableSocketOption(SO_BROADCAST);
 362    }
 363
 364    if ( m_initialRecvBufferSize >= 0 )
 365        SetSocketOption(SO_RCVBUF, m_initialRecvBufferSize);
 366    if ( m_initialSendBufferSize >= 0 )
 367        SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
 368
 369    // we always put our sockets in unblocked mode and handle blocking
 370    // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
 371    UnblockAndRegisterWithEventLoop();
 372}
 373
 374wxSocketError wxSocketImpl::UpdateLocalAddress()
 375{
 376    if ( !m_local.IsOk() )
 377    {
 378        // ensure that we have a valid object using the correct family: correct
 379        // being the same one as our peer uses as we have no other way to
 380        // determine it
 381        m_local.Create(m_peer.GetFamily());
 382    }
 383
 384    WX_SOCKLEN_T lenAddr = m_local.GetLen();
 385    if ( getsockname(m_fd, m_local.GetWritableAddr(), &lenAddr) != 0 )
 386    {
 387        Close();
 388        m_error = wxSOCKET_IOERR;
 389        return m_error;
 390    }
 391
 392    return wxSOCKET_NOERROR;
 393}
 394
 395wxSocketError wxSocketImpl::CreateServer()
 396{
 397    if ( !PreCreateCheck(m_local) )
 398        return m_error;
 399
 400    m_server = true;
 401    m_stream = true;
 402
 403    // do create the socket
 404    m_fd = socket(m_local.GetFamily(), SOCK_STREAM, 0);
 405
 406    if ( m_fd == INVALID_SOCKET )
 407    {
 408        m_error = wxSOCKET_IOERR;
 409        return wxSOCKET_IOERR;
 410    }
 411
 412    PostCreation();
 413
 414    // and then bind to and listen on it
 415    //
 416    // FIXME: should we test for m_dobind here?
 417    if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
 418        m_error = wxSOCKET_IOERR;
 419
 420    if ( IsOk() )
 421    {
 422        if ( listen(m_fd, 5) != 0 )
 423            m_error = wxSOCKET_IOERR;
 424    }
 425
 426    if ( !IsOk() )
 427    {
 428        Close();
 429        return m_error;
 430    }
 431
 432    // finally retrieve the address we effectively bound to
 433    return UpdateLocalAddress();
 434}
 435
 436wxSocketError wxSocketImpl::CreateClient(bool wait)
 437{
 438    if ( !PreCreateCheck(m_peer) )
 439        return m_error;
 440
 441    m_fd = socket(m_peer.GetFamily(), SOCK_STREAM, 0);
 442
 443    if ( m_fd == INVALID_SOCKET )
 444    {
 445        m_error = wxSOCKET_IOERR;
 446        return wxSOCKET_IOERR;
 447    }
 448
 449    PostCreation();
 450
 451    // If a local address has been set, then bind to it before calling connect
 452    if ( m_local.IsOk() )
 453    {
 454        if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
 455        {
 456            Close();
 457            m_error = wxSOCKET_IOERR;
 458            return m_error;
 459        }
 460    }
 461
 462    // Do connect now
 463    int rc = connect(m_fd, m_peer.GetAddr(), m_peer.GetLen());
 464    if ( rc == SOCKET_ERROR )
 465    {
 466        wxSocketError err = GetLastError();
 467        if ( err == wxSOCKET_WOULDBLOCK )
 468        {
 469            m_establishing = true;
 470
 471            // block waiting for connection if we should (otherwise just return
 472            // wxSOCKET_WOULDBLOCK to the caller)
 473            if ( wait )
 474            {
 475                err = SelectWithTimeout(wxSOCKET_CONNECTION_FLAG)
 476                        ? wxSOCKET_NOERROR
 477                        : wxSOCKET_TIMEDOUT;
 478                m_establishing = false;
 479            }
 480        }
 481
 482        m_error = err;
 483    }
 484    else // connected
 485    {
 486        m_error = wxSOCKET_NOERROR;
 487    }
 488
 489    return m_error;
 490}
 491
 492
 493wxSocketError wxSocketImpl::CreateUDP()
 494{
 495    if ( !PreCreateCheck(m_local) )
 496        return m_error;
 497
 498    m_stream = false;
 499    m_server = false;
 500
 501    m_fd = socket(m_local.GetFamily(), SOCK_DGRAM, 0);
 502
 503    if ( m_fd == INVALID_SOCKET )
 504    {
 505        m_error = wxSOCKET_IOERR;
 506        return wxSOCKET_IOERR;
 507    }
 508
 509    PostCreation();
 510
 511    if ( m_dobind )
 512    {
 513        if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
 514        {
 515            Close();
 516            m_error = wxSOCKET_IOERR;
 517            return m_error;
 518        }
 519
 520        return UpdateLocalAddress();
 521    }
 522
 523    return wxSOCKET_NOERROR;
 524}
 525
 526wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
 527{
 528    wxSockAddressStorage from;
 529    WX_SOCKLEN_T fromlen = sizeof(from);
 530    const wxSOCKET_T fd = accept(m_fd, &from.addr, &fromlen);
 531
 532    wxScopeGuard closeSocket = wxMakeGuard(wxClose, fd);
 533
 534    // accepting is similar to reading in the sense that it resets "ready for
 535    // read" flag on the socket
 536    ReenableEvents(wxSOCKET_INPUT_FLAG);
 537
 538    if ( fd == INVALID_SOCKET )
 539        return NULL;
 540
 541    wxSocketManager * const manager = wxSocketManager::Get();
 542    if ( !manager )
 543        return NULL;
 544
 545    wxSocketImpl * const sock = manager->CreateSocket(wxsocket);
 546    if ( !sock )
 547        return NULL;
 548
 549    // Ownership of the socket now passes to wxSocketImpl object.
 550    closeSocket.Dismiss();
 551    sock->m_fd = fd;
 552    sock->m_peer = wxSockAddressImpl(from.addr, fromlen);
 553
 554    sock->UnblockAndRegisterWithEventLoop();
 555
 556    return sock;
 557}
 558
 559
 560void wxSocketImpl::Close()
 561{
 562    if ( m_fd != INVALID_SOCKET )
 563    {
 564        DoClose();
 565        m_fd = INVALID_SOCKET;
 566    }
 567}
 568
 569void wxSocketImpl::Shutdown()
 570{
 571    if ( m_fd != INVALID_SOCKET )
 572    {
 573        shutdown(m_fd, 1 /* SD_SEND */);
 574        Close();
 575    }
 576}
 577
 578/*
 579 *  Sets the timeout for blocking calls. Time is expressed in
 580 *  milliseconds.
 581 */
 582void wxSocketImpl::SetTimeout(unsigned long millis)
 583{
 584    SetTimeValFromMS(m_timeout, millis);
 585}
 586
 587void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
 588{
 589    m_wxsocket->OnRequest(event);
 590}
 591
 592/* Address handling */
 593wxSocketError wxSocketImpl::SetLocal(const wxSockAddressImpl& local)
 594{
 595    /* the socket must be initialized, or it must be a server */
 596    if (m_fd != INVALID_SOCKET && !m_server)
 597    {
 598        m_error = wxSOCKET_INVSOCK;
 599        return wxSOCKET_INVSOCK;
 600    }
 601
 602    if ( !local.IsOk() )
 603    {
 604        m_error = wxSOCKET_INVADDR;
 605        return wxSOCKET_INVADDR;
 606    }
 607
 608    m_local = local;
 609
 610    return wxSOCKET_NOERROR;
 611}
 612
 613wxSocketError wxSocketImpl::SetPeer(const wxSockAddressImpl& peer)
 614{
 615    if ( !peer.IsOk() )
 616    {
 617        m_error = wxSOCKET_INVADDR;
 618        return wxSOCKET_INVADDR;
 619    }
 620
 621    m_peer = peer;
 622
 623    return wxSOCKET_NOERROR;
 624}
 625
 626const wxSockAddressImpl& wxSocketImpl::GetLocal()
 627{
 628    if ( !m_local.IsOk() )
 629        UpdateLocalAddress();
 630
 631    return m_local;
 632}
 633
 634// ----------------------------------------------------------------------------
 635// wxSocketImpl IO
 636// ----------------------------------------------------------------------------
 637
 638// this macro wraps the given expression (normally a syscall) in a loop which
 639// ignores any interruptions, i.e. reevaluates it again if it failed and errno
 640// is EINTR
 641#ifdef __UNIX__
 642    #define DO_WHILE_EINTR( rc, syscall ) \
 643        do { \
 644            rc = (syscall); \
 645        } \
 646        while ( rc == -1 && errno == EINTR )
 647#else
 648    #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
 649#endif
 650
 651int wxSocketImpl::RecvStream(void *buffer, int size)
 652{
 653    int ret;
 654    DO_WHILE_EINTR( ret, recv(m_fd, static_cast<char *>(buffer), size, 0) );
 655
 656    if ( !ret )
 657    {
 658        // receiving 0 bytes for a TCP socket indicates that the connection was
 659        // closed by peer so shut down our end as well (for UDP sockets empty
 660        // datagrams are also possible)
 661        m_establishing = false;
 662        NotifyOnStateChange(wxSOCKET_LOST);
 663
 664        Shutdown();
 665
 666        // do not return an error in this case however
 667    }
 668
 669    return ret;
 670}
 671
 672int wxSocketImpl::SendStream(const void *buffer, int size)
 673{
 674#ifdef wxNEEDS_IGNORE_SIGPIPE
 675    IgnoreSignal ignore(SIGPIPE);
 676#endif
 677
 678    int ret;
 679    DO_WHILE_EINTR( ret, send(m_fd, static_cast<const char *>(buffer), size,
 680                              wxSOCKET_MSG_NOSIGNAL) );
 681
 682    return ret;
 683}
 684
 685int wxSocketImpl::RecvDgram(void *buffer, int size)
 686{
 687    wxSockAddressStorage from;
 688    WX_SOCKLEN_T fromlen = sizeof(from);
 689
 690    int ret;
 691    DO_WHILE_EINTR( ret, recvfrom(m_fd, static_cast<char *>(buffer), size,
 692                                  0, &from.addr, &fromlen) );
 693
 694    if ( ret == SOCKET_ERROR )
 695        return SOCKET_ERROR;
 696
 697    m_peer = wxSockAddressImpl(from.addr, fromlen);
 698    if ( !m_peer.IsOk() )
 699        return -1;
 700
 701    return ret;
 702}
 703
 704int wxSocketImpl::SendDgram(const void *buffer, int size)
 705{
 706    if ( !m_peer.IsOk() )
 707    {
 708        m_error = wxSOCKET_INVADDR;
 709        return -1;
 710    }
 711
 712    int ret;
 713    DO_WHILE_EINTR( ret, sendto(m_fd, static_cast<const char *>(buffer), size,
 714                                0, m_peer.GetAddr(), m_peer.GetLen()) );
 715
 716    return ret;
 717}
 718
 719int wxSocketImpl::Read(void *buffer, int size)
 720{
 721    // server sockets can't be used for IO, only to accept new connections
 722    if ( m_fd == INVALID_SOCKET || m_server )
 723    {
 724        m_error = wxSOCKET_INVSOCK;
 725        return -1;
 726    }
 727
 728    int ret = m_stream ? RecvStream(buffer, size)
 729                       : RecvDgram(buffer, size);
 730
 731    m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
 732
 733    return ret;
 734}
 735
 736int wxSocketImpl::Write(const void *buffer, int size)
 737{
 738    if ( m_fd == INVALID_SOCKET || m_server )
 739    {
 740        m_error = wxSOCKET_INVSOCK;
 741        return -1;
 742    }
 743
 744    int ret = m_stream ? SendStream(buffer, size)
 745                       : SendDgram(buffer, size);
 746
 747    m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
 748
 749    return ret;
 750}
 751
 752// ==========================================================================
 753// wxSocketBase
 754// ==========================================================================
 755
 756// --------------------------------------------------------------------------
 757// Initialization and shutdown
 758// --------------------------------------------------------------------------
 759
 760namespace
 761{
 762
 763// counts the number of calls to Initialize() minus the number of calls to
 764// Shutdown(): we don't really need it any more but it was documented that
 765// Shutdown() must be called the same number of times as Initialize() and using
 766// a counter helps us to check it
 767int gs_socketInitCount = 0;
 768
 769} // anonymous namespace
 770
 771bool wxSocketBase::IsInitialized()
 772{
 773    wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" );
 774
 775    return gs_socketInitCount != 0;
 776}
 777
 778bool wxSocketBase::Initialize()
 779{
 780    wxCHECK_MSG( wxIsMainThread(), false,
 781                 "must be called from the main thread" );
 782
 783    if ( !gs_socketInitCount )
 784    {
 785        wxSocketManager * const manager = wxSocketManager::Get();
 786        if ( !manager || !manager->OnInit() )
 787            return false;
 788    }
 789
 790    gs_socketInitCount++;
 791
 792    return true;
 793}
 794
 795void wxSocketBase::Shutdown()
 796{
 797    wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" );
 798
 799    wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" );
 800
 801    if ( !--gs_socketInitCount )
 802    {
 803        wxSocketManager * const manager = wxSocketManager::Get();
 804        wxCHECK_RET( manager, "should have a socket manager" );
 805
 806        manager->OnExit();
 807    }
 808}
 809
 810// --------------------------------------------------------------------------
 811// Ctor and dtor
 812// --------------------------------------------------------------------------
 813
 814void wxSocketBase::Init()
 815{
 816    m_impl         = NULL;
 817    m_type         = wxSOCKET_UNINIT;
 818
 819    // state
 820    m_flags        = 0;
 821    m_connected    =
 822    m_establishing =
 823    m_reading      =
 824    m_writing      =
 825    m_closed       = false;
 826    m_lcount       = 0;
 827    m_lcount_read  = 0;
 828    m_lcount_write = 0;
 829    m_timeout      = 600;
 830    m_beingDeleted = false;
 831
 832    // pushback buffer
 833    m_unread       = NULL;
 834    m_unrd_size    = 0;
 835    m_unrd_cur     = 0;
 836
 837    // events
 838    m_id           = wxID_ANY;
 839    m_handler      = NULL;
 840    m_clientData   = NULL;
 841    m_notify       = false;
 842    m_eventmask    =
 843    m_eventsgot    = 0;
 844
 845    // when we create the first socket in the main thread we initialize the
 846    // OS-dependent socket stuff: notice that this means that the user code
 847    // needs to call wxSocket::Initialize() itself if the first socket it
 848    // creates is not created in the main thread
 849    if ( wxIsMainThread() )
 850    {
 851        if ( !Initialize() )
 852        {
 853            wxLogError(_("Cannot initialize sockets"));
 854        }
 855    }
 856}
 857
 858wxSocketBase::wxSocketBase()
 859{
 860    Init();
 861}
 862
 863wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
 864{
 865    Init();
 866
 867    SetFlags(flags);
 868
 869    m_type = type;
 870}
 871
 872wxSocketBase::~wxSocketBase()
 873{
 874    // Shutdown and close the socket
 875    if (!m_beingDeleted)
 876        Close();
 877
 878    // Destroy the implementation object
 879    delete m_impl;
 880
 881    // Free the pushback buffer
 882    free(m_unread);
 883}
 884
 885bool wxSocketBase::Destroy()
 886{
 887    // Delayed destruction: the socket will be deleted during the next idle
 888    // loop iteration. This ensures that all pending events have been
 889    // processed.
 890    m_beingDeleted = true;
 891
 892    // Shutdown and close the socket
 893    Close();
 894
 895    // Suppress events from now on
 896    Notify(false);
 897
 898    // Schedule this object for deletion instead of destroying it right now if
 899    // it can have other events pending for it and we have a way to do it.
 900    //
 901    // Notice that sockets used in other threads won't have any events for them
 902    // and we shouldn't use delayed destruction mechanism for them as it's not
 903    // MT-safe.
 904    if ( wxIsMainThread() && wxTheApp )
 905    {
 906        wxTheApp->ScheduleForDestruction(this);
 907    }
 908    else // no app
 909    {
 910        // in wxBase we might have no app object at all, don't leak memory
 911        delete this;
 912    }
 913
 914    return true;
 915}
 916
 917// ----------------------------------------------------------------------------
 918// simple accessors
 919// ----------------------------------------------------------------------------
 920
 921void wxSocketBase::SetError(wxSocketError error)
 922{
 923    m_impl->m_error = error;
 924}
 925
 926wxSocketError wxSocketBase::LastError() const
 927{
 928    return m_impl->GetError();
 929}
 930
 931// --------------------------------------------------------------------------
 932// Basic IO calls
 933// --------------------------------------------------------------------------
 934
 935// The following IO operations update m_lcount:
 936// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
 937bool wxSocketBase::Close()
 938{
 939    // Interrupt pending waits
 940    InterruptWait();
 941
 942    ShutdownOutput();
 943
 944    m_connected = false;
 945    m_establishing = false;
 946    return true;
 947}
 948
 949void wxSocketBase::ShutdownOutput()
 950{
 951    if ( m_impl )
 952        m_impl->Shutdown();
 953}
 954
 955wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
 956{
 957    wxSocketReadGuard read(this);
 958
 959    m_lcount_read = DoRead(buffer, nbytes);
 960    m_lcount = m_lcount_read;
 961
 962    return *this;
 963}
 964
 965wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
 966{
 967    wxCHECK_MSG( m_impl, 0, "socket must be valid" );
 968
 969    // We use pointer arithmetic here which doesn't work with void pointers.
 970    char *buffer = static_cast<char *>(buffer_);
 971    wxCHECK_MSG( buffer, 0, "NULL buffer" );
 972
 973    // Try the push back buffer first, even before checking whether the socket
 974    // is valid to allow reading previously pushed back data from an already
 975    // closed socket.
 976    wxUint32 total = GetPushback(buffer, nbytes, false);
 977    nbytes -= total;
 978    buffer += total;
 979
 980    while ( nbytes )
 981    {
 982        // our socket is non-blocking so Read() will return immediately if
 983        // there is nothing to read yet and it's more efficient to try it first
 984        // before entering DoWait() which is going to start dispatching GUI
 985        // events and, even more importantly, we must do this under Windows
 986        // where we're not going to get notifications about socket being ready
 987        // for reading before we read all the existing data from it
 988        const int ret = !m_impl->m_stream || m_connected
 989                            ? m_impl->Read(buffer, nbytes)
 990                            : 0;
 991        if ( ret == -1 )
 992        {
 993            if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
 994            {
 995                // if we don't want to wait, just return immediately
 996                if ( m_flags & wxSOCKET_NOWAIT_READ )
 997                {
 998                    // this shouldn't be counted as an error in this case
 999                    SetError(wxSOCKET_NOERROR);
1000                    break;
1001                }
1002
1003                // otherwise wait until the socket becomes ready for reading or
1004                // an error occurs on it
1005                if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG) )
1006                {
1007                    // and exit if the timeout elapsed before it did
1008                    SetError(wxSOCKET_TIMEDOUT);
1009                    break;
1010                }
1011
1012                // retry reading
1013                continue;
1014            }
1015            else // "real" error
1016            {
1017                SetError(wxSOCKET_IOERR);
1018                break;
1019            }
1020        }
1021        else if ( ret == 0 )
1022        {
1023            // for connection-oriented (e.g. TCP) sockets we can only read
1024            // 0 bytes if the other end has been closed, and for connectionless
1025            // ones (UDP) this flag doesn't make sense anyhow so we can set it
1026            // to true too without doing any harm
1027            m_closed = true;
1028
1029            // we're not going to read anything else and so if we haven't read
1030            // anything (or not everything in wxSOCKET_WAITALL case) already,
1031            // signal an error
1032            if ( (m_flags & wxSOCKET_WAITALL_READ) || !total )
1033                SetError(wxSOCKET_IOERR);
1034            break;
1035        }
1036
1037        total += ret;
1038
1039        // if we are happy to read something and not the entire nbytes bytes,
1040        // then we're done
1041        if ( !(m_flags & wxSOCKET_WAITALL_READ) )
1042            break;
1043
1044        nbytes -= ret;
1045        buffer += ret;
1046    }
1047
1048    return total;
1049}
1050
1051wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
1052{
1053    struct
1054    {
1055        unsigned char sig[4];
1056        unsigned char len[4];
1057    } msg;
1058
1059    wxSocketReadGuard read(this);
1060
1061    wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL_READ);
1062
1063    bool ok = false;
1064    if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1065    {
1066        wxUint32 sig = (wxUint32)msg.sig[0];
1067        sig |= (wxUint32)(msg.sig[1] << 8);
1068        sig |= (wxUint32)(msg.sig[2] << 16);
1069        sig |= (wxUint32)(msg.sig[3] << 24);
1070
1071        if ( sig == 0xfeeddead )
1072        {
1073            wxUint32 len = (wxUint32)msg.len[0];
1074            len |= (wxUint32)(msg.len[1] << 8);
1075            len |= (wxUint32)(msg.len[2] << 16);
1076            len |= (wxUint32)(msg.len[3] << 24);
1077
1078            wxUint32 len2;
1079            if (len > nbytes)
1080            {
1081                len2 = len - nbytes;
1082                len = nbytes;
1083            }
1084            else
1085                len2 = 0;
1086
1087            // Don't attempt to read if the msg was zero bytes long.
1088            m_lcount_read = len ? DoRead(buffer, len) : 0;
1089            m_lcount = m_lcount_read;
1090
1091            if ( len2 )
1092            {
1093                char discard_buffer[MAX_DISCARD_SIZE];
1094                long discard_len;
1095
1096                // NOTE: discarded bytes don't add to m_lcount.
1097                do
1098                {
1099                    discard_len = len2 > MAX_DISCARD_SIZE
1100                                    ? MAX_DISCARD_SIZE
1101                                    : len2;
1102                    discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
1103                    len2 -= (wxUint32)discard_len;
1104                }
1105                while ((discard_len > 0) && len2);
1106            }
1107
1108            if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1109            {
1110                sig = (wxUint32)msg.sig[0];
1111                sig |= (wxUint32)(msg.sig[1] << 8);
1112                sig |= (wxUint32)(msg.sig[2] << 16);
1113                sig |= (wxUint32)(msg.sig[3] << 24);
1114
1115                if ( sig == 0xdeadfeed )
1116                    ok = true;
1117            }
1118        }
1119    }
1120
1121    if ( !ok )
1122        SetError(wxSOCKET_IOERR);
1123
1124    return *this;
1125}
1126
1127wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
1128{
1129    wxSocketReadGuard read(this);
1130
1131    // Peek() should never block
1132    wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1133
1134    m_lcount = DoRead(buffer, nbytes);
1135
1136    Pushback(buffer, m_lcount);
1137
1138    return *this;
1139}
1140
1141wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
1142{
1143    wxSocketWriteGuard write(this);
1144
1145    m_lcount_write = DoWrite(buffer, nbytes);
1146    m_lcount = m_lcount_write;
1147
1148    return *this;
1149}
1150
1151// This function is a mirror image of DoRead() except that it doesn't use the
1152// push back buffer and doesn't treat 0 return value specially (normally this
1153// shouldn't happen at all here), so please see comments there for explanations
1154wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
1155{
1156    wxCHECK_MSG( m_impl, 0, "socket must be valid" );
1157
1158    const char *buffer = static_cast<const char *>(buffer_);
1159    wxCHECK_MSG( buffer, 0, "NULL buffer" );
1160
1161    wxUint32 total = 0;
1162    while ( nbytes )
1163    {
1164        if ( m_impl->m_stream && !m_connected )
1165        {
1166            if ( (m_flags & wxSOCKET_WAITALL_WRITE) || !total )
1167                SetError(wxSOCKET_IOERR);
1168            break;
1169        }
1170
1171        const int ret = m_impl->Write(buffer, nbytes);
1172        if ( ret == -1 )
1173        {
1174            if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
1175            {
1176                if ( m_flags & wxSOCKET_NOWAIT_WRITE )
1177                    break;
1178
1179                if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
1180                {
1181                    SetError(wxSOCKET_TIMEDOUT);
1182                    break;
1183                }
1184
1185                continue;
1186            }
1187            else // "real" error
1188            {
1189                SetError(wxSOCKET_IOERR);
1190                break;
1191            }
1192        }
1193
1194        total += ret;
1195
1196        if ( !(m_flags & wxSOCKET_WAITALL_WRITE) )
1197            break;
1198
1199        nbytes -= ret;
1200        buffer += ret;
1201    }
1202
1203    return total;
1204}
1205
1206wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
1207{
1208    struct
1209    {
1210        unsigned char sig[4];
1211        unsigned char len[4];
1212    } msg;
1213
1214    wxSocketWriteGuard write(this);
1215
1216    wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL_WRITE);
1217
1218    msg.sig[0] = (unsigned char) 0xad;
1219    msg.sig[1] = (unsigned char) 0xde;
1220    msg.sig[2] = (unsigned char) 0xed;
1221    msg.sig[3] = (unsigned char) 0xfe;
1222
1223    msg.len[0] = (unsigned char) (nbytes & 0xff);
1224    msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1225    msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1226    msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1227
1228    bool ok = false;
1229    if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1230    {
1231        m_lcount_write = DoWrite(buffer, nbytes);
1232        m_lcount = m_lcount_write;
1233        if ( m_lcount_write == nbytes )
1234        {
1235            msg.sig[0] = (unsigned char) 0xed;
1236            msg.sig[1] = (unsigned char) 0xfe;
1237            msg.sig[2] = (unsigned char) 0xad;
1238            msg.sig[3] = (unsigned char) 0xde;
1239            msg.len[0] =
1240            msg.len[1] =
1241            msg.len[2] =
1242            msg.len[3] = (char) 0;
1243
1244            if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1245                ok = true;
1246        }
1247    }
1248
1249    if ( !ok )
1250        SetError(wxSOCKET_IOERR);
1251
1252    return *this;
1253}
1254
1255wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1256{
1257    if (nbytes != 0)
1258        Pushback(buffer, nbytes);
1259
1260    SetError(wxSOCKET_NOERROR);
1261    m_lcount = nbytes;
1262
1263    return *this;
1264}
1265
1266wxSocketBase& wxSocketBase::Discard()
1267{
1268    char *buffer = new char[MAX_DISCARD_SIZE];
1269    wxUint32 ret;
1270    wxUint32 total = 0;
1271
1272    wxSocketReadGuard read(this);
1273
1274    wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1275
1276    do
1277    {
1278        ret = DoRead(buffer, MAX_DISCARD_SIZE);
1279        total += ret;
1280    }
1281    while (ret == MAX_DISCARD_SIZE);
1282
1283    delete[] buffer;
1284    m_lcount = total;
1285    SetError(wxSOCKET_NOERROR);
1286
1287    return *this;
1288}
1289
1290// --------------------------------------------------------------------------
1291// Wait functions
1292// --------------------------------------------------------------------------
1293
1294/*
1295    This function will check for the events specified in the flags parameter,
1296    and it will return a mask indicating which operations can be performed.
1297 */
1298wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
1299                                        const timeval *timeout)
1300{
1301    if ( m_fd == INVALID_SOCKET )
1302        return (wxSOCKET_LOST_FLAG & flags);
1303
1304    struct timeval tv;
1305    if ( timeout )
1306        tv = *timeout;
1307    else
1308        tv.tv_sec = tv.tv_usec = 0;
1309
1310    // prepare the FD sets, passing NULL for the one(s) we don't use
1311    fd_set
1312        readfds, *preadfds = NULL,
1313        writefds, *pwritefds = NULL,
1314        exceptfds;                      // always want to know about errors
1315
1316    if ( flags & wxSOCKET_INPUT_FLAG )
1317        preadfds = &readfds;
1318
1319    if ( flags & wxSOCKET_OUTPUT_FLAG )
1320        pwritefds = &writefds;
1321
1322    // When using non-blocking connect() the client socket becomes connected
1323    // (successfully or not) when it becomes writable but when using
1324    // non-blocking accept() the server socket becomes connected when it
1325    // becomes readable.
1326    if ( flags & wxSOCKET_CONNECTION_FLAG )
1327    {
1328        if ( m_server )
1329            preadfds = &readfds;
1330        else
1331            pwritefds = &writefds;
1332    }
1333
1334    if ( preadfds )
1335    {
1336        wxFD_ZERO(preadfds);
1337        wxFD_SET(m_fd, preadfds);
1338    }
1339
1340    if ( pwritefds )
1341    {
1342        wxFD_ZERO(pwritefds);
1343        wxFD_SET(m_fd, pwritefds);
1344    }
1345
1346    wxFD_ZERO(&exceptfds);
1347    wxFD_SET(m_fd, &exceptfds);
1348
1349    const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1350
1351    // check for errors first
1352    if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
1353    {
1354        m_establishing = false;
1355
1356        return wxSOCKET_LOST_FLAG & flags;
1357    }
1358
1359    if ( rc == 0 )
1360        return 0;
1361
1362    wxASSERT_MSG( rc == 1, "unexpected select() return value" );
1363
1364    wxSocketEventFlags detected = 0;
1365    if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1366    {
1367        // check for the case of a server socket waiting for connection
1368        if ( m_server && (flags & wxSOCKET_CONNECTION_FLAG) )
1369        {
1370            int error;
1371            SOCKOPTLEN_T len = sizeof(error);
1372            m_establishing = false;
1373            getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1374
1375            if ( error )
1376                detected = wxSOCKET_LOST_FLAG;
1377            else
1378                detected |= wxSOCKET_CONNECTION_FLAG;
1379        }
1380        else // not called to get non-blocking accept() status
1381        {
1382            detected |= wxSOCKET_INPUT_FLAG;
1383        }
1384    }
1385
1386    if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
1387    {
1388        // check for the case of non-blocking connect()
1389        if ( m_establishing && !m_server )
1390        {
1391            int error;
1392            SOCKOPTLEN_T len = sizeof(error);
1393            m_establishing = false;
1394            getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1395
1396            if ( error )
1397                detected = wxSOCKET_LOST_FLAG;
1398            else
1399                detected |= wxSOCKET_CONNECTION_FLAG;
1400        }
1401        else // not called to get non-blocking connect() status
1402        {
1403            detected |= wxSOCKET_OUTPUT_FLAG;
1404        }
1405    }
1406
1407    return detected & flags;
1408}
1409
1410int
1411wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1412{
1413    // Use either the provided timeout or the default timeout value associated
1414    // with this socket.
1415    //
1416    // TODO: allow waiting forever, see #9443
1417    const long timeout = seconds == -1 ? m_timeout * 1000
1418                                       : seconds * 1000 + milliseconds;
1419
1420    return DoWait(timeout, flags);
1421}
1422
1423int
1424wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
1425{
1426    wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" );
1427
1428    // we're never going to become ready in a TCP client if we're not connected
1429    // any more (OTOH a server can call this to precisely wait for a connection
1430    // so do wait for it in this case and UDP client is never "connected")
1431    if ( !m_impl->IsServer() &&
1432            m_impl->m_stream && !m_connected && !m_establishing )
1433        return -1;
1434
1435    // This can be set to true from Interrupt() to exit this function a.s.a.p.
1436    m_interrupt = false;
1437
1438
1439    const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1440
1441    // Get the active event loop which we'll use for the message dispatching
1442    // when running in the main thread unless this was explicitly disabled by
1443    // setting wxSOCKET_BLOCK flag
1444    wxEventLoopBase *eventLoop;
1445    if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
1446    {
1447        eventLoop = wxEventLoop::GetActive();
1448    }
1449    else // in worker thread
1450    {
1451        // We never dispatch messages from threads other than the main one.
1452        eventLoop = NULL;
1453    }
1454
1455    // Make sure the events we're interested in are enabled before waiting for
1456    // them: this is really necessary here as otherwise this could happen:
1457    //  1. DoRead(wxSOCKET_WAITALL) is called
1458    //  2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
1459    //  3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
1460    //     is called and wxSOCKET_INPUT_FLAG events are disabled in it
1461    //  4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
1462    //     are still disabled and we block forever
1463    //
1464    // More elegant solution would be nice but for now simply re-enabling the
1465    // events here will do
1466    m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
1467
1468
1469    // Wait until we receive the event we're waiting for or the timeout expires
1470    // (but note that we always execute the loop at least once, even if timeout
1471    // is 0 as this is used for polling)
1472    int rc = 0;
1473    for ( bool firstTime = true; !m_interrupt; firstTime = false )
1474    {
1475        long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1476        if ( timeLeft < 0 )
1477        {
1478            if ( !firstTime )
1479                break;   // timed out
1480
1481            timeLeft = 0;
1482        }
1483
1484        wxSocketEventFlags events;
1485        if ( eventLoop )
1486        {
1487            // reset them before starting to wait
1488            m_eventsgot = 0;
1489
1490            eventLoop->DispatchTimeout(timeLeft);
1491
1492            events = m_eventsgot;
1493        }
1494        else // no event loop or waiting in another thread
1495        {
1496            // as explained below, we should always check for wxSOCKET_LOST_FLAG
1497            timeval tv;
1498            SetTimeValFromMS(tv, timeLeft);
1499            events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
1500        }
1501
1502        // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1503        // it, as continuing to wait for anything else after getting it is
1504        // pointless
1505        if ( events & wxSOCKET_LOST_FLAG )
1506        {
1507            m_connected = false;
1508            m_establishing = false;
1509            rc = -1;
1510            break;
1511        }
1512
1513        // otherwise mask out the bits we're not interested in
1514        events &= flags;
1515
1516        // Incoming connection (server) or connection established (client)?
1517        if ( events & wxSOCKET_CONNECTION_FLAG )
1518        {
1519            m_connected = true;
1520            m_establishing = false;
1521            rc = true;
1522            break;
1523        }
1524
1525        // Data available or output buffer ready?
1526        if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
1527        {
1528            rc = true;
1529            break;
1530        }
1531    }
1532
1533    return rc;
1534}
1535
1536bool wxSocketBase::Wait(long seconds, long milliseconds)
1537{
1538    return DoWait(seconds, milliseconds,
1539                  wxSOCKET_INPUT_FLAG |
1540                  wxSOCKET_OUTPUT_FLAG |
1541                  wxSOCKET_CONNECTION_FLAG) != 0;
1542}
1543
1544bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1545{
1546    // Check pushback buffer before entering DoWait
1547    if ( m_unread )
1548        return true;
1549
1550    // Check if the socket is not already ready for input, if it is, there is
1551    // no need to start waiting for it (worse, we'll actually never get a
1552    // notification about the socket becoming ready if it is already under
1553    // Windows)
1554    if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
1555        return true;
1556
1557    return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG) != 0;
1558}
1559
1560
1561bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1562{
1563    if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1564        return true;
1565
1566    return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG) != 0;
1567}
1568
1569bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1570{
1571    return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG) == -1;
1572}
1573
1574// --------------------------------------------------------------------------
1575// Miscellaneous
1576// --------------------------------------------------------------------------
1577
1578//
1579// Get local or peer address
1580//
1581
1582bool wxSocketBase::GetPeer(wxSockAddress& addr) const
1583{
1584    wxCHECK_MSG( m_impl, false, "invalid socket" );
1585
1586    const wxSockAddressImpl& peer = m_impl->GetPeer();
1587    if ( !peer.IsOk() )
1588        return false;
1589
1590    addr.SetAddress(peer);
1591
1592    return true;
1593}
1594
1595bool wxSocketBase::GetLocal(wxSockAddress& addr) const
1596{
1597    wxCHECK_MSG( m_impl, false, "invalid socket" );
1598
1599    const wxSockAddressImpl& local = m_impl->GetLocal();
1600    if ( !local.IsOk() )
1601        return false;
1602
1603    addr.SetAddress(local);
1604
1605    return true;
1606}
1607
1608//
1609// Save and restore socket state
1610//
1611
1612void wxSocketBase::SaveState()
1613{
1614    wxSocketState *state;
1615
1616    state = new wxSocketState();
1617
1618    state->m_flags      = m_flags;
1619    state->m_notify     = m_notify;
1620    state->m_eventmask  = m_eventmask;
1621    state->m_clientData = m_clientData;
1622
1623    m_states.Append(state);
1624}
1625
1626void wxSocketBase::RestoreState()
1627{
1628    wxList::compatibility_iterator node;
1629    wxSocketState *state;
1630
1631    node = m_states.GetLast();
1632    if (!node)
1633        return;
1634
1635    state = (wxSocketState *)node->GetData();
1636
1637    m_flags      = state->m_flags;
1638    m_notify     = state->m_notify;
1639    m_eventmask  = state->m_eventmask;
1640    m_clientData = state->m_clientData;
1641
1642    m_states.Erase(node);
1643    delete state;
1644}
1645
1646//
1647// Timeout and flags
1648//
1649
1650void wxSocketBase::SetTimeout(long seconds)
1651{
1652    m_timeout = seconds;
1653
1654    if (m_impl)
1655        m_impl->SetTimeout(m_timeout * 1000);
1656}
1657
1658void wxSocketBase::SetFlags(wxSocketFlags flags)
1659{
1660    // Do some sanity checking on the flags used: not all values can be used
1661    // together.
1662    wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1663                  !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1664                  "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1665                  "wxSOCKET_NOWAIT doesn't make sense" );
1666
1667    m_flags = flags;
1668}
1669
1670
1671// --------------------------------------------------------------------------
1672// Event handling
1673// --------------------------------------------------------------------------
1674
1675void wxSocketBase::OnRequest(wxSocketNotify notification)
1676{
1677    wxSocketEventFlags flag = 0;
1678    switch ( notification )
1679    {
1680        case wxSOCKET_INPUT:
1681            flag = wxSOCKET_INPUT_FLAG;
1682            break;
1683
1684        case wxSOCKET_OUTPUT:
1685            flag = wxSOCKET_OUTPUT_FLAG;
1686            break;
1687
1688        case wxSOCKET_CONNECTION:
1689            flag = wxSOCKET_CONNECTION_FLAG;
1690
1691            // we're now successfully connected
1692            m_connected = true;
1693            m_establishing = false;
1694
1695            // error was previously set to wxSOCKET_WOULDBLOCK, but this is not
1696            // the case any longer
1697            SetError(wxSOCKET_NOERROR);
1698            break;
1699
1700        case wxSOCKET_LOST:
1701            flag = wxSOCKET_LOST_FLAG;
1702
1703            // if we lost the connection the socket is now closed and not
1704            // connected any more
1705            m_connected = false;
1706            m_closed = true;
1707            break;
1708
1709        default:
1710            wxFAIL_MSG( "unknown wxSocket notification" );
1711    }
1712
1713    // remember the events which were generated for this socket, we're going to
1714    // use this in DoWait()
1715    m_eventsgot |= flag;
1716
1717    // send the wx event if enabled and we're interested in it
1718    if ( m_notify && (m_eventmask & flag) && m_handler )
1719    {
1720        // don't generate the events when we're inside DoWait() called from our
1721        // own code as we are going to consume the data that has just become
1722        // available ourselves and the user code won't see it at all
1723        if ( (notification == wxSOCKET_INPUT && m_reading) ||
1724                (notification == wxSOCKET_OUTPUT && m_writing) )
1725        {
1726            return;
1727        }
1728
1729        wxSocketEvent event(m_id);
1730        event.m_event      = notification;
1731        event.m_clientData = m_clientData;
1732        event.SetEventObject(this);
1733
1734        m_handler->AddPendingEvent(event);
1735    }
1736}
1737
1738void wxSocketBase::Notify(bool notify)
1739{
1740    m_notify = notify;
1741}
1742
1743void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1744{
1745    m_eventmask = flags;
1746}
1747
1748void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1749{
1750    m_handler = &handler;
1751    m_id      = id;
1752}
1753
1754// --------------------------------------------------------------------------
1755// Pushback buffer
1756// --------------------------------------------------------------------------
1757
1758void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1759{
1760    if (!size) return;
1761
1762    if (m_unread == NULL)
1763        m_unread = malloc(size);
1764    else
1765    {
1766        void *tmp;
1767
1768        tmp = malloc(m_unrd_size + size);
1769        memcpy((char *)tmp + size, m_unread, m_unrd_size);
1770        free(m_unread);
1771
1772        m_unread = tmp;
1773    }
1774
1775    m_unrd_size += size;
1776
1777    memcpy(m_unread, buffer, size);
1778}
1779
1780wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1781{
1782    wxCHECK_MSG( buffer, 0, "NULL buffer" );
1783
1784    if (!m_unrd_size)
1785        return 0;
1786
1787    if (size > (m_unrd_size-m_unrd_cur))
1788        size = m_unrd_size-m_unrd_cur;
1789
1790    memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1791
1792    if (!peek)
1793    {
1794        m_unrd_cur += size;
1795        if (m_unrd_size == m_unrd_cur)
1796        {
1797            free(m_unread);
1798            m_unread = NULL;
1799            m_unrd_size = 0;
1800            m_unrd_cur  = 0;
1801        }
1802    }
1803
1804    return size;
1805}
1806
1807
1808// ==========================================================================
1809// wxSocketServer
1810// ==========================================================================
1811
1812// --------------------------------------------------------------------------
1813// Ctor
1814// --------------------------------------------------------------------------
1815
1816wxSocketServer::wxSocketServer(const wxSockAddress& addr,
1817                               wxSocketFlags flags)
1818              : wxSocketBase(flags, wxSOCKET_SERVER)
1819{
1820    wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
1821
1822    wxSocketManager * const manager = wxSocketManager::Get();
1823    m_impl = manager ? manager->CreateSocket(*this) : NULL;
1824
1825    if (!m_impl)
1826    {
1827        wxLogTrace( wxTRACE_Socket, wxT("*** Failed to create m_impl") );
1828        return;
1829    }
1830
1831    // Setup the socket as server
1832    m_impl->SetLocal(addr.GetAddress());
1833
1834    if (GetFlags() & wxSOCKET_REUSEADDR) {
1835        m_impl->SetReusable();
1836    }
1837    if (GetFlags() & wxSOCKET_BROADCAST) {
1838        m_impl->SetBroadcast();
1839    }
1840    if (GetFlags() & wxSOCKET_NOBIND) {
1841        m_impl->DontDoBind();
1842    }
1843
1844    if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1845    {
1846        wxDELETE(m_impl);
1847
1848        wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") );
1849        return;
1850    }
1851
1852    // Notice that we need a cast as wxSOCKET_T is 64 bit under Win64 and that
1853    // the cast is safe because a wxSOCKET_T is a handle and so limited to 32
1854    // (or, actually, even 24) bit values anyhow.
1855    wxLogTrace( wxTRACE_Socket, wxT("wxSocketServer on fd %u"),
1856                static_cast<unsigned>(m_impl->m_fd) );
1857}
1858
1859// ------…

Large files files are truncated, but you can click here to view the full file