]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/socket.cpp
wxGTK now chooses the best visual X offers,
[wxWidgets.git] / src / common / socket.cpp
index 0585cddd1b6d16832c1aaa3d1fd6e7d486cabb52..052078b3b48ae5951831dce65d57556e85c69eec 100644 (file)
@@ -35,6 +35,11 @@ typedef int socklen_t ;
 #include <wx/timer.h>
 #include <wx/utils.h>
 
+// IRIX requires bstring.h be included to use select()
+#ifdef sgi
+    #include <bstring.h>
+#endif // IRIX
+
 // Not enough OS behaviour defined for wxStubs
 #ifndef __WXSTUBS__
 
@@ -209,8 +214,6 @@ wxSocketBase::~wxSocketBase()
   // First, close the file descriptor.
   Close();
 
-  m_internal->FinalizeSocket();
-
   if (m_unread)
     free(m_unread);
   // Unregister from the handler database.
@@ -228,8 +231,8 @@ bool wxSocketBase::Close()
 {
   if (m_fd != INVALID_SOCKET) 
   {
-    // Pause all running socket thread.
-    m_internal->PauseSocket();
+    if (m_notify_state == TRUE)
+      Notify(FALSE);
 
     // Shutdown the connection.
     shutdown(m_fd, 2);
@@ -262,6 +265,65 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
   return *this;
 }
 
+wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
+{
+  unsigned long len, len2, sig;
+  struct {
+    char sig[4];
+    char len[4];
+  } 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
+
+  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;
+
+  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;
+
+  // len2 is incorrectly computed in the original; this sequence is
+  // the fix
+  if (len > nbytes) {
+    len2 = len - nbytes;
+    len = nbytes;
+  }
+  else
+    len2 = 0;
+
+  // the "len &&" in the following statement is necessary so that
+  // we don't attempt to read (and possibly hang the system)
+  // if the message was zero bytes long
+  if (len && Read(buffer, len).LastCount() != len)
+    return *this;
+  if (len2 && (Read(NULL, len2).LastCount() != len2))
+    return *this;
+  if (Read((char *)&msg, sizeof(msg)).LastCount() != 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;
+// ERROR
+// we return *this either way, so a smart optimizer will
+// optimize the following sequence out; I'm leaving it in anyway
+  if (sig != 0xdeadfeed)
+    return *this;
+
+  return *this;
+}
+
 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
 {
   m_lcount = GetPushback(buffer, nbytes, TRUE);
@@ -284,9 +346,54 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
   return *this;
 }
 
+wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
+{
+  struct {
+    char sig[4];
+    char len[4];
+  } msg;
+
+  // warning about 'cast truncates constant value'
+#ifdef __VISUALC__
+    #pragma warning(disable: 4310)
+#endif // __VISUALC__
+
+  msg.sig[0] = (char) 0xad;
+  msg.sig[1] = (char) 0xde;
+  msg.sig[2] = (char) 0xed;
+  msg.sig[3] = (char) 0xfe;
+
+    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;
+
+  if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
+    return *this;
+  if (Write(buffer, nbytes).LastCount() < nbytes)
+    return *this;
+
+  msg.sig[0] = (char) 0xed;
+  msg.sig[1] = (char) 0xfe;
+  msg.sig[2] = (char) 0xad;
+  msg.sig[3] = (char) 0xde;
+  msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
+  Write((char *)&msg, sizeof(msg));
+
+  return *this;
+
+#ifdef __VISUALC__
+    #pragma warning(default: 4310)
+#endif // __VISUALC__
+}
+
 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
 {
-  CreatePushbackAfter(buffer, nbytes);
+  m_lcount = 0;
+  if (nbytes != 0) {
+    CreatePushbackAfter(buffer, nbytes);
+    m_lcount = nbytes;
+  }
   return *this;
 }
 
@@ -306,7 +413,7 @@ bool wxSocketBase::IsData() const
   tv.tv_usec = 0;
   FD_ZERO(&sock_set);
   FD_SET(m_fd, &sock_set);
-  select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
+  select(m_fd+1, &sock_set, NULL, NULL, &tv);
 
   m_internal->ReleaseFD();
 
@@ -426,7 +533,9 @@ void wxSocketBase::RestoreState()
   state = (SocketState *)node->Data();
 
   SetFlags(state->socket_flags);
+  m_internal->AcquireData();
   m_neededreq = state->evt_notify_state;
+  m_internal->ReleaseData();
   m_cbk       = state->c_callback;
   m_cdata     = state->c_callback_data;
   Notify(state->notify_state);
@@ -545,20 +654,25 @@ void wxSocketBase::SetNotify(wxRequestNotify flags)
   if (m_type != SOCK_SERVER)
     flags &= ~REQ_ACCEPT;
 
+  m_internal->AcquireData();
   m_neededreq = flags;
+  m_internal->ReleaseData();
   if (m_neededreq == 0)
-    m_internal->DisableWaiter();
+    m_internal->StopWaiter();
   else
     Notify(m_notify_state);
 }
 
 void wxSocketBase::Notify(bool notify)
 {
+  m_notify_state = notify;
+  if (m_fd == INVALID_SOCKET)
+    return;
+
   if (notify)
-    m_internal->EnableWaiter();
+    m_internal->ResumeWaiter();
   else
-    m_internal->DisableWaiter();
-  m_notify_state = notify;
+    m_internal->StopWaiter();
 }
 
 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
@@ -574,7 +688,7 @@ void wxSocketBase::OnRequest(wxRequestEvent req_evt)
     // OldOnNotify(req_evt);
 
     // We disable the event reporting.
-    SetNotify(m_neededreq & ~notify);
+    m_neededreq &= ~notify;
   }
 }
 
@@ -586,14 +700,14 @@ wxSocketEvent::wxSocketEvent(int id)
   SetEventType(type);
 }
 
-wxObject *wxSocketEvent::Clone() const
+void wxSocketEvent::CopyObject(wxObject& obj_d) const
 {
-  wxSocketEvent *event = (wxSocketEvent *)wxEvent::Clone();
+  wxSocketEvent *event = (wxSocketEvent *)&obj_d;
+
+  wxEvent::CopyObject(obj_d);
 
   event->m_skevt = m_skevt;
   event->m_socket = m_socket;
-
-  return event;
 }
 
 void wxSocketBase::OldOnNotify(wxRequestEvent evt)
@@ -679,7 +793,6 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
   SockRequest *buf = new SockRequest;
 
   SaveState();
-  m_internal->DisableWaiter(); 
   buf->buffer = buffer;
   buf->size = nbytes;
   buf->done = FALSE;
@@ -690,10 +803,10 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
   buf->timeout = 1000;
   buf_timed_out = FALSE;
 
-  if (m_flags & SPEED
+  if ((m_flags & SPEED) != 0
     m_internal->QueueRequest(buf, FALSE);
   else
-    if (m_flags & NOWAIT
+    if ((m_flags & NOWAIT) != 0
       m_internal->QueueRequest(buf, TRUE);
     else 
       m_internal->QueueRequest(buf, TRUE);
@@ -735,7 +848,9 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
     return;
   }
 
-  m_internal->InitializeSocket();
+  m_internal->SetFD(m_fd);
+
+  Notify(TRUE);
 }
 
 // --------------------------------------------------------------
@@ -746,8 +861,12 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock)
 {
   int fd2;
 
-  if ((fd2 = accept(m_fd, 0, 0)) < 0)
+  m_internal->AcquireFD();
+  if ((fd2 = accept(m_fd, 0, 0)) < 0) {
+    m_internal->ReleaseFD();
     return FALSE;
+  }
+  m_internal->ReleaseFD();
 
   struct linger linger;
   linger.l_onoff = 0;
@@ -762,7 +881,9 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock)
   sock.m_fd = fd2;
   sock.m_connected = TRUE;
 
-  sock.m_internal->InitializeSocket();
+  sock.m_internal->SetFD(fd2);
+
+  sock.m_internal->ResumeWaiter();
 
   return TRUE;
 }
@@ -844,9 +965,7 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
   if (connect(m_fd, remote, len) != 0)
     return FALSE;
 
-  // Initializes the background threads ...
-  // --------------------------------------
-  m_internal->InitializeSocket();
+  m_internal->SetFD(m_fd);
 
   // Enables bg events.
   // ------------------
@@ -872,11 +991,10 @@ void wxSocketClient::OnRequest(wxRequestEvent evt)
   {
     if (m_connected) 
     {
-      SetNotify(m_neededreq & ~REQ_CONNECT);
+      m_neededreq &= ~REQ_CONNECT;
       return;
     }
     m_connected = TRUE;
-    OldOnNotify(EVT_CONNECT);
     return;
   }
   wxSocketBase::OnRequest(evt);
@@ -1060,31 +1178,6 @@ wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
   return client;
 }
 
-#ifdef __WINDOWS__
-// --------------------------------------------------------------
-// --------- wxSocketHandler: Windows specific methods ----------
-// --------------------------------------------------------------
-
-UINT wxSocketHandler::NewMessage(wxSocketBase *sock)
-{
-  internal->firstAvailableMsg++;
-  smsg_list->Append(internal->firstAvailableMsg, sock);
-  return internal->firstAvailableMsg;
-}
-
-void wxSocketHandler::DestroyMessage(UINT msg)
-{
-  wxNode *node = smsg_list->Find(msg);
-  delete node;
-}
-
-HWND wxSocketHandler::GetHWND() const
-{
-  return internal->sockWin;
-}
-
-#endif
-
 bool wxSocketModule::OnInit() 
 {
   wxSocketHandler::master = new wxSocketHandler();