X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ca17eff36b7084f213ab3c233b6183ef8bd1a345..6f349458f6903083bd967f52624a5e639733ad5d:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index b06e2490fb..7bb51dabdc 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ ///////////////////////////////////////////////////////////////////////////// // wxSocket headers ///////////////////////////////////////////////////////////////////////////// -#include #include #include @@ -72,7 +72,7 @@ wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags, wxEvtHandler(), m_socket(NULL), m_flags(_flags), m_type(_type), m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG), - m_lcount(0), m_timeout(3600), + m_lcount(0), m_timeout(600), m_unread(NULL), m_unrd_size(0), m_unrd_cur(0), m_cbk(NULL), m_cdata(NULL), m_connected(FALSE), m_notify_state(FALSE), m_id(-1), @@ -85,7 +85,7 @@ wxSocketBase::wxSocketBase() : wxEvtHandler(), m_socket(NULL), m_flags(SPEED | WAITALL), m_type(SOCK_UNINIT), m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG), - m_lcount(0), m_timeout(3600), + m_lcount(0), m_timeout(600), m_unread(NULL), m_unrd_size(0), m_unrd_cur(0), m_cbk(NULL), m_cdata(NULL), m_connected(FALSE), m_notify_state(FALSE), m_id(-1), @@ -128,36 +128,66 @@ bool wxSocketBase::Close() // -------------------------------------------------------------- // wxSocketBase base IO function // -------------------------------------------------------------- +class _wxSocketInternalTimer: public wxTimer { + public: + int *m_state; + unsigned long m_new_val; + + void Notify() + { + *m_state = m_new_val; // Change the value + } +}; -int wxSocketBase::DeferRead(char *buffer, size_t nbytes) +int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes) { - GSocketEventFlags old_event_flags; + wxSocketEventFlags old_event_flags; bool old_notify_state; + // Timer for timeout + _wxSocketInternalTimer timer; wxASSERT(m_defering == NO_DEFER); + // Set the defering mode to READ. m_defering = DEFER_READ; + // Save the old state. old_event_flags = NeededReq(); old_notify_state = m_notify_state; + // Set the new async flag. SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG); Notify(TRUE); + // Set the current buffer. m_defer_buffer = buffer; m_defer_nbytes = nbytes; + m_defer_timer = &timer; + + timer.m_state = (int *)&m_defer_buffer; + timer.m_new_val = 0; + + timer.Start(m_timeout * 1000, FALSE); + + // Wait for buffer completion. while (m_defer_buffer != NULL) wxYield(); + timer.Stop(); + + // Restore the old state. Notify(old_notify_state); SetNotify(old_event_flags); + // Disable defering mode. m_defering = NO_DEFER; + m_defer_timer = NULL; + // Return the number of bytes read from the socket. return nbytes-m_defer_nbytes; } -wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes) { int ret = 1; @@ -202,7 +232,7 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes) { unsigned long len, len2, sig; struct { @@ -211,23 +241,23 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) } msg; // sig should be an explicit 32-bit unsigned integer; I've seen - // compilers in which size_t was actually a 16-bit unsigned integer + // compilers in which wxUint32 was actually a 16-bit unsigned integer Read((char *)&msg, sizeof(msg)); if (m_lcount != sizeof(msg)) return *this; sig = msg.sig[0] & 0xff; - sig |= (size_t)(msg.sig[1] & 0xff) << 8; - sig |= (size_t)(msg.sig[2] & 0xff) << 16; - sig |= (size_t)(msg.sig[3] & 0xff) << 24; + sig |= (wxUint32)(msg.sig[1] & 0xff) << 8; + sig |= (wxUint32)(msg.sig[2] & 0xff) << 16; + sig |= (wxUint32)(msg.sig[3] & 0xff) << 24; if (sig != 0xfeeddead) return *this; len = msg.len[0] & 0xff; - len |= (size_t)(msg.len[1] & 0xff) << 8; - len |= (size_t)(msg.len[2] & 0xff) << 16; - len |= (size_t)(msg.len[3] & 0xff) << 24; + len |= (wxUint32)(msg.len[1] & 0xff) << 8; + len |= (wxUint32)(msg.len[2] & 0xff) << 16; + len |= (wxUint32)(msg.len[3] & 0xff) << 24; // len2 is incorrectly computed in the original; this sequence is // the fix @@ -249,9 +279,9 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) return *this; sig = msg.sig[0] & 0xff; - sig |= (size_t)(msg.sig[1] & 0xff) << 8; - sig |= (size_t)(msg.sig[2] & 0xff) << 16; - sig |= (size_t)(msg.sig[3] & 0xff) << 24; + sig |= (wxUint32)(msg.sig[1] & 0xff) << 8; + sig |= (wxUint32)(msg.sig[2] & 0xff) << 16; + sig |= (wxUint32)(msg.sig[3] & 0xff) << 24; // ERROR if (sig != 0xdeadfeed) @@ -260,7 +290,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes) { Read(buffer, nbytes); CreatePushbackAfter(buffer, nbytes); @@ -268,26 +298,43 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) return *this; } -int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes) +int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes) { - GSocketEventFlags old_event_flags; + wxSocketEventFlags old_event_flags; bool old_notify_state; + // Timer for timeout + _wxSocketInternalTimer timer; wxASSERT(m_defering == NO_DEFER); m_defering = DEFER_WRITE; + // Save the old state old_event_flags = NeededReq(); old_notify_state = m_notify_state; SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG); Notify(TRUE); + // Set the current buffer m_defer_buffer = (char *)buffer; m_defer_nbytes = nbytes; + + // Start timer + timer.m_state = (int *)&m_defer_buffer; + timer.m_new_val = 0; + + m_defer_timer = &timer; + timer.Start(m_timeout * 1000, FALSE); + while (m_defer_buffer != NULL) wxYield(); + // Stop timer + m_defer_timer = NULL; + timer.Stop(); + + // Restore the old state Notify(old_notify_state); SetNotify(old_event_flags); @@ -296,7 +343,7 @@ int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes) return nbytes-m_defer_nbytes; } -wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes) { int ret; @@ -311,7 +358,7 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) +wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes) { struct { char sig[4]; @@ -328,7 +375,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) msg.sig[2] = (char) 0xed; msg.sig[3] = (char) 0xfe; - msg.len[0] = (char) nbytes & 0xff; + msg.len[0] = (char) nbytes & 0xff; msg.len[1] = (char) (nbytes >> 8) & 0xff; msg.len[2] = (char) (nbytes >> 16) & 0xff; msg.len[3] = (char) (nbytes >> 24) & 0xff; @@ -352,7 +399,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) #endif // __VISUALC__ } -wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes) { m_lcount = 0; if (nbytes != 0) { @@ -370,11 +417,11 @@ bool wxSocketBase::IsData() const return (GSocket_DataAvailable(m_socket)); } -void wxSocketBase::DoDefer(GSocketEvent req_evt) +void wxSocketBase::DoDefer(wxSocketNotify req_evt) { int ret; - if (req_evt == GSOCK_LOST) { + if (req_evt == wxSOCKET_LOST) { Close(); m_defer_buffer = NULL; return; @@ -396,11 +443,15 @@ void wxSocketBase::DoDefer(GSocketEvent req_evt) if (ret < 0) m_defer_nbytes++; + // If we are waiting for all bytes to be acquired, keep the defering modei + // enabled. if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) { m_defer_buffer = NULL; Notify(FALSE); - } else + } else { m_defer_buffer += ret; + m_defer_timer->Start(m_timeout * 1000, FALSE); + } } // --------------------------------------------------------------------- @@ -410,7 +461,7 @@ void wxSocketBase::Discard() { #define MAX_BUFSIZE (10*1024) char *my_data = new char[MAX_BUFSIZE]; - size_t recv_size = MAX_BUFSIZE; + wxUint32 recv_size = MAX_BUFSIZE; SaveState(); SetFlags(NOWAIT | SPEED); @@ -522,16 +573,6 @@ char *wxSocketBase::CallbackData(char *data) // --------- wxSocketBase wait functions ------------------------ // -------------------------------------------------------------- -class _wxSocketInternalTimer: public wxTimer { - public: - int *m_state; - - void Notify() - { - *m_state = GSOCK_MAX_EVENT; // Just to say it's a timeout. - } -}; - static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata) { int *state = (int *)cdata; @@ -542,25 +583,30 @@ static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata) bool wxSocketBase::_Wait(long seconds, long milliseconds, int type) { bool old_notify_state = m_notify_state; - int state = 0; + int state = -1; _wxSocketInternalTimer timer; if (!m_connected || !m_socket) return FALSE; + // Set the variable to change timer.m_state = &state; + timer.m_new_val = GSOCK_MAX_EVENT; + // Disable the previous handler Notify(FALSE); + // Set the timeout timer.Start(seconds * 1000 + milliseconds, TRUE); - GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state); + GSocket_SetCallback(m_socket, type, wx_socket_wait, (char *)&state); - while (state == 0) + while (state == -1) wxYield(); - GSocket_UnsetFallback(m_socket, type); + GSocket_UnsetCallback(m_socket, type); timer.Stop(); + // Notify will restore automatically the old GSocket flags Notify(old_notify_state); return (state != GSOCK_MAX_EVENT); @@ -591,7 +637,7 @@ bool wxSocketBase::WaitForLost(long seconds, long milliseconds) // --------- wxSocketBase callback management ------------------- // -------------------------------------------------------------- -GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt) +wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify evt) { switch (evt) { @@ -619,7 +665,7 @@ wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const return m_flags; } -void wxSocketBase::SetNotify(GSocketEventFlags flags) +void wxSocketBase::SetNotify(wxSocketEventFlags flags) { /* Check if server */ if (m_type != SOCK_SERVER) @@ -640,7 +686,7 @@ static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata) { wxSocketBase *sckobj = (wxSocketBase *)cdata; - sckobj->OnRequest(event); + sckobj->OnRequest((wxSocketNotify)event); } void wxSocketBase::Notify(bool notify) @@ -649,18 +695,18 @@ void wxSocketBase::Notify(bool notify) if (!m_socket) return; - GSocket_UnsetFallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG | + GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG); if (!notify) return; - GSocket_SetFallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this); + GSocket_SetCallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this); } -void wxSocketBase::OnRequest(GSocketEvent req_evt) +void wxSocketBase::OnRequest(wxSocketNotify req_evt) { wxSocketEvent event(m_id); - GSocketEventFlags notify = EventToNotify(req_evt); + wxSocketEventFlags notify = EventToNotify(req_evt); if (m_defering != NO_DEFER) { DoDefer(req_evt); @@ -669,16 +715,16 @@ void wxSocketBase::OnRequest(GSocketEvent req_evt) if ((m_neededreq & notify) == notify) { event.m_socket = this; - event.m_skevt = req_evt; + event.m_skevt = req_evt; ProcessEvent(event); OldOnNotify(req_evt); } - if (req_evt == GSOCK_LOST) + if (req_evt == wxSOCKET_LOST) Close(); } -void wxSocketBase::OldOnNotify(GSocketEvent evt) +void wxSocketBase::OldOnNotify(wxSocketNotify evt) { } @@ -696,7 +742,7 @@ void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id) // --------- wxSocketBase pushback library ---------------------- // -------------------------------------------------------------- -void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) +void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 size) { char *curr_pos; @@ -711,7 +757,7 @@ void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) m_unrd_size += size; } -void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size) +void wxSocketBase::CreatePushbackBefore(const char *buffer, wxUint32 size) { if (m_unread == NULL) m_unread = (char *)malloc(size); @@ -730,7 +776,7 @@ void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size) memcpy(m_unread, buffer, size); } -size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek) +wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek) { if (!m_unrd_size) return 0; @@ -825,8 +871,10 @@ wxSocketClient::~wxSocketClient() // -------------------------------------------------------------- // --------- wxSocketClient Connect functions ------------------- // -------------------------------------------------------------- -bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) +bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait) { + GSocketError err; + if (IsConnected()) Close(); @@ -843,12 +891,27 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) m_connected = FALSE; + // GRG: If wait == FALSE, then set the socket to + // nonblocking. I will set it back to blocking later, + // but I am not sure if this is really a good idea. + // IMO, all GSockets objects used in wxSocket should + // be non-blocking. + // -------------------------------- + if (!wait) + GSocket_SetNonBlocking(m_socket, TRUE); + // Update the flags of m_socket. SetFlags(m_flags); + + // Try to connect GSocket_SetPeer(m_socket, addr_man.GetAddress()); - if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR) { + err = GSocket_Connect(m_socket, GSOCK_STREAMED); + + if (!wait) + GSocket_SetNonBlocking(m_socket, FALSE); + + if (err != GSOCK_NOERROR) return FALSE; - } // Enables bg events. // ------------------ @@ -868,9 +931,9 @@ bool wxSocketClient::WaitOnConnect(long seconds, long microseconds) return m_connected; } -void wxSocketClient::OnRequest(GSocketEvent evt) +void wxSocketClient::OnRequest(wxSocketNotify evt) { - if (evt == GSOCK_CONNECTION) + if ((GSocketEvent)evt == GSOCK_CONNECTION) { if (m_connected) { @@ -912,8 +975,7 @@ class WXDLLEXPORT wxSocketModule: public wxModule { DECLARE_DYNAMIC_CLASS(wxSocketModule) public: bool OnInit() { - GSocket_Init(); - return TRUE; + return GSocket_Init(); } void OnExit() { GSocket_Cleanup();