]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/socket.cpp
added GetHeaderValue() (patch 974427)
[wxWidgets.git] / src / common / socket.cpp
index 6e41b0e4c31b391baae2c93427cccaba073acf1b..bbbdc01e59faf100ce37ac5b2633c413e33cfd25 100644 (file)
@@ -54,7 +54,7 @@ WX_CHECK_BUILD_OPTIONS("wxNet")
 
 // what to do within waits: we have 2 cases: from the main thread itself we
 // have to call wxYield() to let the events (including the GUI events and the
-// low-level (not wxWindows) events from GSocket) be processed. From another
+// low-level (not wxWidgets) events from GSocket) be processed. From another
 // thread it is enough to just call wxThread::Yield() which will give away the
 // rest of our time slice: the explanation is that the events will be processed
 // by the main thread anyhow, without calling wxYield(), but we don't want to
@@ -94,10 +94,6 @@ public:
   wxSocketEventFlags       m_eventmask;
   bool                     m_notify;
   void                    *m_clientData;
-#if WXWIN_COMPATIBILITY
-  wxSocketBase::wxSockCbk  m_cbk;
-  char                    *m_cdata;
-#endif // WXWIN_COMPATIBILITY
 
 public:
   wxSocketState() : wxObject() {}
@@ -126,6 +122,26 @@ bool wxSocketBase::Initialize()
 {
     if ( !m_countInit++ )
     {
+#ifdef __WXMSW__
+        /*
+            The following asserting might be neccessary for linux as well,
+            but I cannot verify this.
+        */
+        wxASSERT(wxThread::IsMain(), 
+            wxT("To use sockets in a secondary thread, ")
+            wxT("call wxSocketBase::Initialize() from the main thread."));
+        /*
+            Details: Initialize() creates a hidden window as a sink for socket
+            events, such as 'read completed'. wxMSW has only one message loop
+            for the main thread. If Initialize is called in a secondary thread,
+            the socket window will be created for the secondary thread, but
+            since there is no message loop on this thread, it will never
+            receive events and all socket operations will time out.
+            BTW, the main thread must not be stopped using sleep or block
+            on a semaphore (a bad idea in any case) or socket operations 
+            will time out.
+        */
+#endif
         wxAppTraits *traits = wxAppConsole::GetInstance() ?
                               wxAppConsole::GetInstance()->GetTraits() : NULL;
         GSocketGUIFunctionsTable *functions = 
@@ -184,10 +200,6 @@ void wxSocketBase::Init()
   m_clientData   = NULL;
   m_notify       = FALSE;
   m_eventmask    = 0;
-#if WXWIN_COMPATIBILITY
-  m_cbk          = NULL;
-  m_cdata        = NULL;
-#endif // WXWIN_COMPATIBILITY
 
   if ( !IsInitialized() )
   {
@@ -311,7 +323,6 @@ wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
 wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
 {
   int total;
-  int ret = 1;
 
   // Try the pushback buffer first
   total = GetPushback(buffer, nbytes, FALSE);
@@ -333,6 +344,7 @@ wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
   // wxSOCKET_BLOCK
   // wxSOCKET_NONE
   //
+  int ret;
   if (m_flags & wxSOCKET_NOWAIT)
   {
     GSocket_SetNonBlocking(m_socket, 1);
@@ -512,7 +524,6 @@ wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
 wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
 {
   wxUint32 total = 0;
-  int ret = 1;
 
   // If the socket is invalid or parameters are ill, return immediately
   if (!m_socket || !buffer || !nbytes)
@@ -524,6 +535,7 @@ wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
   // wxSOCKET_BLOCK
   // wxSOCKET_NONE
   //
+  int ret;
   if (m_flags & wxSOCKET_NOWAIT)
   {
     GSocket_SetNonBlocking(m_socket, 1);
@@ -686,6 +698,10 @@ bool wxSocketBase::_Wait(long seconds,
   else
     timeout = m_timeout * 1000;
 
+#if !defined(wxUSE_GUI) || !wxUSE_GUI
+  GSocket_SetTimeout(m_socket, timeout);
+#endif 
+
   // Wait in an active polling loop.
   //
   // NOTE: We duplicate some of the code in OnRequest, but this doesn't
@@ -758,6 +774,7 @@ bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
                                       GSOCK_LOST_FLAG);
 }
 
+
 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
 {
   return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
@@ -824,10 +841,6 @@ void wxSocketBase::SaveState()
   state->m_notify     = m_notify;
   state->m_eventmask  = m_eventmask;
   state->m_clientData = m_clientData;
-#if WXWIN_COMPATIBILITY
-  state->m_cbk        = m_cbk;
-  state->m_cdata      = m_cdata;
-#endif // WXWIN_COMPATIBILITY
 
   m_states.Append(state);
 }
@@ -847,11 +860,7 @@ void wxSocketBase::RestoreState()
   m_notify     = state->m_notify;
   m_eventmask  = state->m_eventmask;
   m_clientData = state->m_clientData;
-#if WXWIN_COMPATIBILITY
-  m_cbk        = state->m_cbk;
-  m_cdata      = state->m_cdata;
-#endif // WXWIN_COMPATIBILITY
-
+  
   m_states.Erase(node);
   delete state;
 }
@@ -874,30 +883,6 @@ void wxSocketBase::SetFlags(wxSocketFlags flags)
 }
 
 
-// --------------------------------------------------------------------------
-// Callbacks (now obsolete - use events instead)
-// --------------------------------------------------------------------------
-
-#if WXWIN_COMPATIBILITY
-
-wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
-{
-  wxSockCbk old_cbk = cbk_;
-
-  m_cbk = cbk_;
-  return old_cbk;
-}
-
-char *wxSocketBase::CallbackData(char *data)
-{
-  char *old_data = m_cdata;
-
-  m_cdata = data;
-  return old_data;
-}
-
-#endif // WXWIN_COMPATIBILITY
-
 // --------------------------------------------------------------------------
 // Event handling
 // --------------------------------------------------------------------------
@@ -970,6 +955,7 @@ void wxSocketBase::OnRequest(wxSocketNotify notification)
   // Schedule the event
 
   wxSocketEventFlags flag = 0;
+  wxUnusedVar(flag);
   switch (notification)
   {
     case GSOCK_INPUT:      flag = GSOCK_INPUT_FLAG; break;
@@ -992,11 +978,6 @@ void wxSocketBase::OnRequest(wxSocketNotify notification)
 
       m_handler->AddPendingEvent(event);
     }
-
-#if WXWIN_COMPATIBILITY
-    if (m_cbk)
-      m_cbk(*this, notification, m_cdata);
-#endif // WXWIN_COMPATIBILITY
   }
 }
 
@@ -1166,6 +1147,27 @@ bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
   return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
 }
 
+bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
+{
+    if (GSocket_GetSockOpt(m_socket, level, optname, optval, optlen) 
+        != GSOCK_NOERROR)
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+bool wxSocketBase::SetOption(int level, int optname, const void *optval, 
+                              int optlen)
+{
+    if (GSocket_SetSockOpt(m_socket, level, optname, optval, optlen) 
+        != GSOCK_NOERROR)
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
 // ==========================================================================
 // wxSocketClient
 // ==========================================================================
@@ -1261,9 +1263,12 @@ wxDatagramSocket::wxDatagramSocket( wxSockAddress& addr,
   m_socket = GSocket_new();
 
   if(!m_socket)
+  {
+    wxASSERT_MSG( 0, _T("datagram socket not new'd") );
     return;
-
+  }
   // Setup the socket as non connection oriented
+  GSocket_Unstreamed(m_socket);
   GSocket_SetLocal(m_socket, addr.GetAddress());
   if( GSocket_SetNonOriented(m_socket) != GSOCK_NOERROR )
   {