summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
0304608)
(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
int GetFD() { return m_fd; }
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);
void QueueRequest(SockRequest *request, bool async);
void WaitForEnd(SockRequest *request);
if (ret == 0)
// If nothing happened, we wait for 100 ms.
wxUsleep(10);
if (ret == 0)
// If nothing happened, we wait for 100 ms.
wxUsleep(10);
*/
// Check whether we should exit.
*/
// Check whether we should exit.
wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
{
m_socket = socket;
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()
{
m_request_locker.Lock();
}
wxSocketInternal::~wxSocketInternal()
{
+ wxASSERT(m_thread_requester == NULL);
+ wxASSERT(m_thread_waiter == NULL);
m_request_locker.Unlock();
m_request_locker.Unlock();
- delete m_thread_waiter;
- delete m_thread_requester;
}
// ----------------------------------------------------------------------
}
// ----------------------------------------------------------------------
-// ----------------------------------------------------------------------
-// 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())));
- 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);
+
+ // Send a signal to the requester.
if (m_requests.Number() == 0)
m_socket_cond.Signal();
if (m_requests.Number() == 0)
m_socket_cond.Signal();
m_socket_locker.Unlock();
m_socket_locker.Unlock();
- // Finish the destruction of the thread "requester".
+ // Finish the destruction of the requester.
m_thread_requester->Delete();
m_thread_requester->Delete();
-void wxSocketInternal::PauseSocket()
-{
- DisableWaiter();
+ delete m_thread_requester;
+ m_thread_requester = NULL;
-void wxSocketInternal::ResumeSocket()
+void wxSocketInternal::ResumeWaiter()
-void wxSocketInternal::EnableWaiter()
-{
- wxASSERT(m_thread_waiter != NULL);
- if (!m_thread_waiter->IsAlive() || !m_thread_waiter->IsPaused())
+ if (m_thread_waiter != NULL)
- 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)
- m_thread_waiter->Pause();
+ m_thread_waiter->Delete();
+
+ delete m_thread_waiter;
+ m_thread_waiter = NULL;
+*/
}
// ----------------------------------------------------------------------
}
// ----------------------------------------------------------------------
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
{
if (async) {
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);
m_request_locker.Lock();
request->done = FALSE;
m_requests.Append((wxObject *)request);
} else {
m_request_locker.Lock();
} else {
m_request_locker.Lock();
// First, close the file descriptor.
Close();
// First, close the file descriptor.
Close();
- m_internal->FinalizeSocket();
-
if (m_unread)
free(m_unread);
// Unregister from the handler database.
if (m_unread)
free(m_unread);
// Unregister from the handler database.
{
if (m_fd != INVALID_SOCKET)
{
{
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);
// Shutdown the connection.
shutdown(m_fd, 2);
m_neededreq = flags;
if (m_neededreq == 0)
m_neededreq = flags;
if (m_neededreq == 0)
- m_internal->DisableWaiter();
+ m_internal->StopWaiter();
else
Notify(m_notify_state);
}
else
Notify(m_notify_state);
}
- m_internal->EnableWaiter();
+ m_internal->ResumeWaiter();
- m_internal->DisableWaiter();
+ m_internal->StopWaiter();
}
void wxSocketBase::OnRequest(wxRequestEvent req_evt)
}
void wxSocketBase::OnRequest(wxRequestEvent req_evt)
// OldOnNotify(req_evt);
// We disable the event reporting.
// OldOnNotify(req_evt);
// We disable the event reporting.
- SetNotify(m_neededreq & ~notify);
+ m_neededreq &= ~notify;
SockRequest *buf = new SockRequest;
SaveState();
SockRequest *buf = new SockRequest;
SaveState();
- m_internal->DisableWaiter();
+ m_internal->StopWaiter();
buf->buffer = buffer;
buf->size = nbytes;
buf->done = FALSE;
buf->buffer = buffer;
buf->size = nbytes;
buf->done = FALSE;
- m_internal->InitializeSocket();
}
// --------------------------------------------------------------
}
// --------------------------------------------------------------
sock.m_fd = fd2;
sock.m_connected = TRUE;
sock.m_fd = fd2;
sock.m_connected = TRUE;
- sock.m_internal->InitializeSocket();
+ sock.m_internal->ResumeWaiter();
if (connect(m_fd, remote, len) != 0)
return FALSE;
if (connect(m_fd, remote, len) != 0)
return FALSE;
- // Initializes the background threads ...
- // --------------------------------------
- m_internal->InitializeSocket();
-
// Enables bg events.
// ------------------
Notify(TRUE);
// Enables bg events.
// ------------------
Notify(TRUE);
- SetNotify(m_neededreq & ~REQ_CONNECT);
+ m_neededreq &= ~REQ_CONNECT;
return;
}
m_connected = TRUE;
return;
}
m_connected = TRUE;
- OldOnNotify(EVT_CONNECT);
return;
}
wxSocketBase::OnRequest(evt);
return;
}
wxSocketBase::OnRequest(evt);
// next wake up the threads waiting for us (OTOH, this function won't return
// until someone waited for us!)
// 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->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;
// delete both C++ thread object and terminate the OS thread object
// GL: This is very ugly and buggy ...
// delete this;