]> git.saurik.com Git - wxWidgets.git/commitdiff
* implemented VZ's idea about creating and destroying bg threads.
authorGuilhem Lavaux <lavaux@easynet.fr>
Sat, 8 May 1999 12:18:53 +0000 (12:18 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Sat, 8 May 1999 12:18:53 +0000 (12:18 +0000)
  (PB with the destruction of waiter: I think it's a race problem but
   I can't localize it if someone finds it please mail it to me)
* Fixed race condition in threadpsx.cpp.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2364 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/sckint.h
src/common/sckint.cpp
src/common/socket.cpp
src/unix/threadpsx.cpp

index e90dfb939c8f09dca44cf391f7d95b16dd23ff06..e42b7bfb9ed889fb0a4e42b4a23eb1eda89ea5f5 100644 (file)
@@ -115,12 +115,10 @@ class wxSocketInternal {
 
   int GetFD() { return m_fd; }
   
-  void InitializeSocket();
-  void FinalizeSocket();
-  void PauseSocket();
-  void ResumeSocket();
-  void EnableWaiter();
-  void DisableWaiter();
+  void ResumeWaiter();
+  void StopWaiter();
+  void ResumeRequester();
+  void StopRequester();
 
   void QueueRequest(SockRequest *request, bool async);
   void WaitForEnd(SockRequest *request);
index a177aed7886caaf469ec7211b5c1b79ab091b890..7d372c038459cb7827c088cb7637a2963af9b121 100644 (file)
@@ -165,14 +165,13 @@ void *SocketWaiter::Entry()
     if (ret == 0)
       // If nothing happened, we wait for 100 ms.
       wxUsleep(10);
-    else
-      wxYield();
 */
 
     // Check whether we should exit.
-    if (TestDestroy())
+    if (TestDestroy()) {
       return NULL;
- }
+    }
+  }
   return NULL;
 }
 
@@ -320,16 +319,16 @@ void *SocketRequester::Entry()
 wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
 {
   m_socket = socket;
-  m_thread_waiter = new SocketWaiter(socket, this);
-  m_thread_requester = new SocketRequester(socket, this);
+  m_thread_requester = NULL;
+  m_thread_waiter = NULL;
   m_request_locker.Lock();
 }
 
 wxSocketInternal::~wxSocketInternal()
 {
+  wxASSERT(m_thread_requester == NULL);
+  wxASSERT(m_thread_waiter == NULL);
   m_request_locker.Unlock();
-  delete m_thread_waiter;
-  delete m_thread_requester;
 }
 
 // ----------------------------------------------------------------------
@@ -376,82 +375,69 @@ void wxSocketInternal::ReleaseFD()
   m_fd_locker.Unlock();
 }
 
-// ----------------------------------------------------------------------
-// InitializeSocket: called by wxSocketBase to initialize the daemons with
-// a new file descriptor and to create them
-// ----------------------------------------------------------------------
-void wxSocketInternal::InitializeSocket()
+void wxSocketInternal::ResumeRequester()
 {
-  wxASSERT( ((!m_thread_waiter->IsAlive() || m_thread_waiter->IsPaused()) &&
-            (!m_thread_requester->IsAlive() || m_thread_requester->IsPaused())));
+  wxThreadError err;
 
-  m_thread_waiter->m_fd = m_socket->m_fd;
-  m_thread_requester->m_fd = m_socket->m_fd;
+  wxASSERT(m_thread_requester == NULL);
 
-  if (m_thread_waiter->IsPaused())
-    ResumeSocket();
-  else {
-    wxThreadError err;
+  m_thread_requester = new SocketRequester(m_socket, this);
+  m_thread_requester->m_fd = m_socket->m_fd;
 
-    err = m_thread_waiter->Create();
-    wxASSERT(err == wxTHREAD_NO_ERROR);
-    err = m_thread_requester->Create();
-    wxASSERT(err == wxTHREAD_NO_ERROR);
+  err = m_thread_requester->Create();
+  wxASSERT(err == wxTHREAD_NO_ERROR);
 
-    err = m_thread_waiter->Run();
-    wxASSERT(err == wxTHREAD_NO_ERROR);
-    err = m_thread_requester->Run();
-    wxASSERT(err == wxTHREAD_NO_ERROR);
-  }
+  err = m_thread_requester->Run();
+  wxASSERT(err == wxTHREAD_NO_ERROR);
 }
 
-
-// ----------------------------------------------------------------------
-// InitializeSocket: called by wxSocketBase to destroy daemons
-// ----------------------------------------------------------------------
-void wxSocketInternal::FinalizeSocket()
+void wxSocketInternal::StopRequester()
 {
-  ResumeSocket();
-
-  m_thread_waiter->Delete();
-
-  // Send a signal to the thread "requester".
+  wxASSERT(m_thread_requester != NULL);
 
   m_socket_locker.Lock();
+
+  // Send a signal to the requester.
   if (m_requests.Number() == 0)
     m_socket_cond.Signal();
+
   m_socket_locker.Unlock();
 
-  // Finish the destruction of the thread "requester".
+  // Finish the destruction of the requester.
   m_thread_requester->Delete();
-}
 
-void wxSocketInternal::PauseSocket()
-{
-  DisableWaiter();
+  delete m_thread_requester;
+  m_thread_requester = NULL;
 }
 
-void wxSocketInternal::ResumeSocket()
+void wxSocketInternal::ResumeWaiter()
 {
-  EnableWaiter();
-}
+  wxThreadError err;
 
-void wxSocketInternal::EnableWaiter()
-{
-  wxASSERT(m_thread_waiter != NULL);
-  if (!m_thread_waiter->IsAlive() || !m_thread_waiter->IsPaused())
+  if (m_thread_waiter != NULL)
     return;
 
-  m_thread_waiter->Resume();
+  m_thread_waiter = new SocketWaiter(m_socket, this);
+  m_thread_waiter->m_fd = m_socket->m_fd;
+
+  err = m_thread_waiter->Create();
+  wxASSERT(err == wxTHREAD_NO_ERROR);
+
+  err = m_thread_waiter->Run();
+  wxASSERT(err == wxTHREAD_NO_ERROR);
 }
 
-void wxSocketInternal::DisableWaiter()
+void wxSocketInternal::StopWaiter()
 {
-  wxASSERT(m_thread_waiter != NULL); 
-  if (!m_thread_waiter->IsAlive() || m_thread_waiter->IsPaused())
+/*
+  if (m_thread_waiter == NULL)
     return;
 
-  m_thread_waiter->Pause();
+  m_thread_waiter->Delete();
+
+  delete m_thread_waiter;
+  m_thread_waiter = NULL;
+*/
 }
 
 // ----------------------------------------------------------------------
@@ -460,6 +446,9 @@ void wxSocketInternal::DisableWaiter()
 void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
 {
   if (async) {
+    if (m_thread_requester == NULL)
+      ResumeRequester();
+
     m_request_locker.Lock();
     request->done = FALSE;
     m_requests.Append((wxObject *)request);
@@ -478,7 +467,6 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
           wxThread::Yield();
         }
     }
-
   } else {
     m_request_locker.Lock();
 
index 47004a9dde7233a7741e2192aa5cdc3dc2d802fb..2372865175a5af539076b86c05773be378eb93e7 100644 (file)
@@ -209,8 +209,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 +226,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);
@@ -547,7 +545,7 @@ void wxSocketBase::SetNotify(wxRequestNotify flags)
 
   m_neededreq = flags;
   if (m_neededreq == 0)
-    m_internal->DisableWaiter();
+    m_internal->StopWaiter();
   else
     Notify(m_notify_state);
 }
@@ -559,9 +557,9 @@ void wxSocketBase::Notify(bool notify)
     return;
 
   if (notify)
-    m_internal->EnableWaiter();
+    m_internal->ResumeWaiter();
   else
-    m_internal->DisableWaiter();
+    m_internal->StopWaiter();
 }
 
 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
@@ -577,7 +575,7 @@ void wxSocketBase::OnRequest(wxRequestEvent req_evt)
     // OldOnNotify(req_evt);
 
     // We disable the event reporting.
-    SetNotify(m_neededreq & ~notify);
+    m_neededreq &= ~notify;
   }
 }
 
@@ -682,7 +680,7 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
   SockRequest *buf = new SockRequest;
 
   SaveState();
-  m_internal->DisableWaiter(); 
+  m_internal->StopWaiter(); 
   buf->buffer = buffer;
   buf->size = nbytes;
   buf->done = FALSE;
@@ -738,7 +736,7 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
     return;
   }
 
-  m_internal->InitializeSocket();
+  Notify(TRUE);
 }
 
 // --------------------------------------------------------------
@@ -769,7 +767,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock)
   sock.m_fd = fd2;
   sock.m_connected = TRUE;
 
-  sock.m_internal->InitializeSocket();
+  sock.m_internal->ResumeWaiter();
 
   return TRUE;
 }
@@ -851,10 +849,6 @@ 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();
-
   // Enables bg events.
   // ------------------
   Notify(TRUE);
@@ -879,11 +873,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);
index d7dac9c864feb37215c1ece6295119bfe5f4a41a..ca1c7731b64e264a0bf06cb69f46b0e07d6e0488 100644 (file)
@@ -675,10 +675,10 @@ void wxThread::Exit(void *status)
 
     // next wake up the threads waiting for us (OTOH, this function won't return
     // until someone waited for us!)
-    p_internal->SignalExit();
-
     p_internal->SetState(STATE_EXITED);
 
+    p_internal->SignalExit();
+
     // delete both C++ thread object and terminate the OS thread object
     // GL: This is very ugly and buggy ...
 //    delete this;