* prgodlgg.h: Update() use wxString instead of 'char *'
* wxThread: fixes (all should work fluently now) * wxSocket: it is at last usable on my computer GTK/GLIB problem : reenabling the idle event propagation causes very strange problem (Instruction pointer/memory) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2490 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
49828363f8
commit
9111db6802
@ -53,7 +53,7 @@ public:
|
|||||||
@param newmsg if used, new message to display
|
@param newmsg if used, new message to display
|
||||||
@returns true if ABORT button has not been pressed
|
@returns true if ABORT button has not been pressed
|
||||||
*/
|
*/
|
||||||
bool Update(int value = -1, const char *newmsg = NULL);
|
bool Update(int value = -1, const wxString& newmsg = "");
|
||||||
|
|
||||||
/** Can be called to continue after the cancel button has been pressed, but
|
/** Can be called to continue after the cancel button has been pressed, but
|
||||||
the program decided to continue the operation (e.g., user didn't
|
the program decided to continue the operation (e.g., user didn't
|
||||||
|
@ -118,6 +118,7 @@ class wxSocketInternal {
|
|||||||
void ReleaseFD();
|
void ReleaseFD();
|
||||||
|
|
||||||
int GetFD() { return m_fd; }
|
int GetFD() { return m_fd; }
|
||||||
|
void SetFD(int fd) { m_fd = fd; }
|
||||||
|
|
||||||
void ResumeWaiter();
|
void ResumeWaiter();
|
||||||
void StopWaiter();
|
void StopWaiter();
|
||||||
|
@ -137,7 +137,7 @@ MyFrame::MyFrame():
|
|||||||
wxSocketHandler::Master();
|
wxSocketHandler::Master();
|
||||||
|
|
||||||
sock = new MyClient();
|
sock = new MyClient();
|
||||||
sock->SetFlags(wxSocketBase::WAITALL);
|
sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED));
|
||||||
wxSocketHandler::Master().Register(sock);
|
wxSocketHandler::Master().Register(sock);
|
||||||
sock->frame = this;
|
sock->frame = this;
|
||||||
sock->SetNotify(wxSocketBase::REQ_LOST);
|
sock->SetNotify(wxSocketBase::REQ_LOST);
|
||||||
@ -162,8 +162,11 @@ void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt))
|
|||||||
if (sock->IsConnected())
|
if (sock->IsConnected())
|
||||||
sock->Close();
|
sock->Close();
|
||||||
|
|
||||||
|
/*
|
||||||
wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server",
|
wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server",
|
||||||
"Connect ...", "localhost");
|
"Connect ...", "localhost");
|
||||||
|
*/
|
||||||
|
wxString hname = "localhost";
|
||||||
addr.Hostname(hname);
|
addr.Hostname(hname);
|
||||||
addr.Service(3000);
|
addr.Service(3000);
|
||||||
sock->SetNotify(0);
|
sock->SetNotify(0);
|
||||||
|
@ -132,7 +132,7 @@ void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
|
|||||||
if (sock2 == NULL)
|
if (sock2 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sock2->SetFlags(wxSocketBase::NONE);
|
sock2->SetFlags(wxSocketBase::SPEED);
|
||||||
sock2->Notify(TRUE);
|
sock2->Notify(TRUE);
|
||||||
sock2->SetEventHandler(*this, SKDEMO_SOCKET);
|
sock2->SetEventHandler(*this, SKDEMO_SOCKET);
|
||||||
server->SetNotify(wxSocketBase::REQ_ACCEPT);
|
server->SetNotify(wxSocketBase::REQ_ACCEPT);
|
||||||
@ -154,6 +154,7 @@ MyFrame::MyFrame(wxFrame *frame):
|
|||||||
wxSocketHandler::Master().Register(sock);
|
wxSocketHandler::Master().Register(sock);
|
||||||
sock->SetNotify(wxSocketBase::REQ_ACCEPT);
|
sock->SetNotify(wxSocketBase::REQ_ACCEPT);
|
||||||
sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
|
sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
|
||||||
|
sock->SetFlags(wxSocketBase::SPEED);
|
||||||
sock->Notify(TRUE);
|
sock->Notify(TRUE);
|
||||||
nb_clients = 0;
|
nb_clients = 0;
|
||||||
|
|
||||||
|
@ -440,6 +440,9 @@
|
|||||||
/* Define if you have all functions to set thread priority */
|
/* Define if you have all functions to set thread priority */
|
||||||
#undef HAVE_THREAD_PRIORITY_FUNCTIONS
|
#undef HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
|
|
||||||
|
/* Define if you can specify exit functions to a thread */
|
||||||
|
#undef HAVE_THREAD_CLEANUP_FUNCTIONS
|
||||||
|
|
||||||
/* Define if your system has its own `getloadavg' function. */
|
/* Define if your system has its own `getloadavg' function. */
|
||||||
#undef HAVE_GETLOADAVG
|
#undef HAVE_GETLOADAVG
|
||||||
|
|
||||||
|
@ -527,7 +527,6 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
|
|||||||
wxEvent *event_main;
|
wxEvent *event_main;
|
||||||
wxCriticalSectionLocker locker(*m_eventsLocker);
|
wxCriticalSectionLocker locker(*m_eventsLocker);
|
||||||
|
|
||||||
|
|
||||||
// check that we are really in a child thread
|
// check that we are really in a child thread
|
||||||
wxASSERT( !wxThread::IsMain() );
|
wxASSERT( !wxThread::IsMain() );
|
||||||
|
|
||||||
@ -543,7 +542,7 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
|
|||||||
wxPendingEventsLocker->Leave();
|
wxPendingEventsLocker->Leave();
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
if (g_isIdle) wxapp_install_idle_handler();
|
// if (g_isIdle) wxapp_install_idle_handler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: socket.cpp
|
// Name: sckint.cpp
|
||||||
// Purpose: Socket handler classes
|
// Purpose: Socket internal classes
|
||||||
// Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
|
// Authors: Guilhem Lavaux
|
||||||
// Davidson(1995) in wxWeb)
|
// Created: April 1999
|
||||||
// Created: April 1997
|
// Updated:
|
||||||
// Updated: April 1999
|
|
||||||
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
|
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
|
||||||
// RCS_ID: $Id$
|
// RCS_ID: $Id$
|
||||||
// License: see wxWindows license
|
// License: see wxWindows license
|
||||||
@ -87,7 +86,8 @@
|
|||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
SocketWaiter::SocketWaiter(wxSocketBase *socket,
|
SocketWaiter::SocketWaiter(wxSocketBase *socket,
|
||||||
wxSocketInternal *internal)
|
wxSocketInternal *internal)
|
||||||
: m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
: wxThread(),
|
||||||
|
m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,9 +110,9 @@ void SocketWaiter::ProcessReadEvent()
|
|||||||
|
|
||||||
// Else, no error => there is something to be read else
|
// Else, no error => there is something to be read else
|
||||||
// we've lost the connection.
|
// we've lost the connection.
|
||||||
if (ret > 0)
|
if (ret > 0) {
|
||||||
m_socket->OnRequest(wxSocketBase::EVT_READ);
|
m_socket->OnRequest(wxSocketBase::EVT_READ);
|
||||||
else {
|
} else {
|
||||||
m_socket->OnRequest(wxSocketBase::EVT_LOST);
|
m_socket->OnRequest(wxSocketBase::EVT_LOST);
|
||||||
Exit(NULL);
|
Exit(NULL);
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ void *SocketWaiter::Entry()
|
|||||||
FD_SET(m_fd, &sockwr_set);
|
FD_SET(m_fd, &sockwr_set);
|
||||||
|
|
||||||
m_internal->AcquireFD();
|
m_internal->AcquireFD();
|
||||||
ret = select(FD_SETSIZE, &sockrd_set, &sockwr_set, NULL, &tv);
|
ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
|
||||||
m_internal->ReleaseFD();
|
m_internal->ReleaseFD();
|
||||||
|
|
||||||
if (FD_ISSET(m_fd, &sockrd_set))
|
if (FD_ISSET(m_fd, &sockrd_set))
|
||||||
@ -180,7 +180,8 @@ void *SocketWaiter::Entry()
|
|||||||
|
|
||||||
SocketRequester::SocketRequester(wxSocketBase *socket,
|
SocketRequester::SocketRequester(wxSocketBase *socket,
|
||||||
wxSocketInternal *internal)
|
wxSocketInternal *internal)
|
||||||
: m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
: wxThread(),
|
||||||
|
m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ bool SocketRequester::WaitFor(wxSocketBase::wxRequestNotify req, int millisec)
|
|||||||
FD_SET(m_fd, &sockwr_set);
|
FD_SET(m_fd, &sockwr_set);
|
||||||
|
|
||||||
m_internal->AcquireFD();
|
m_internal->AcquireFD();
|
||||||
ret = select(FD_SETSIZE, &sockrd_set, &sockwr_set, NULL, &tv);
|
ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
|
||||||
m_internal->ReleaseFD();
|
m_internal->ReleaseFD();
|
||||||
|
|
||||||
return (ret != 0);
|
return (ret != 0);
|
||||||
@ -253,6 +254,11 @@ void SocketRequester::ProcessWriteEvent(SockRequest *req)
|
|||||||
int ret;
|
int ret;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (!WaitFor(wxSocketBase::REQ_WRITE, req->timeout)) {
|
||||||
|
m_internal->EndRequest(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_internal->AcquireFD();
|
m_internal->AcquireFD();
|
||||||
ret = send(m_fd, req->buffer, req->size, 0);
|
ret = send(m_fd, req->buffer, req->size, 0);
|
||||||
m_internal->ReleaseFD();
|
m_internal->ReleaseFD();
|
||||||
@ -287,13 +293,15 @@ void *SocketRequester::Entry()
|
|||||||
{
|
{
|
||||||
SockRequest *req;
|
SockRequest *req;
|
||||||
|
|
||||||
|
m_internal->m_request_locker.Lock();
|
||||||
while (1) {
|
while (1) {
|
||||||
// Wait for a new request or a destroy message.
|
// Wait for a new request or a destroy message.
|
||||||
req = m_internal->WaitForReq();
|
req = m_internal->WaitForReq();
|
||||||
m_internal->m_end_requester.Lock();
|
m_internal->m_end_requester.Lock();
|
||||||
if (TestDestroy() || req == NULL) {
|
if (req == NULL) {
|
||||||
m_internal->m_invalid_requester = TRUE;
|
m_internal->m_invalid_requester = TRUE;
|
||||||
m_internal->m_end_requester.Unlock();
|
m_internal->m_end_requester.Unlock();
|
||||||
|
m_internal->m_request_locker.Unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
m_internal->m_end_requester.Unlock();
|
m_internal->m_end_requester.Unlock();
|
||||||
@ -328,7 +336,6 @@ wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
|
|||||||
m_thread_requester = NULL;
|
m_thread_requester = NULL;
|
||||||
m_thread_waiter = NULL;
|
m_thread_waiter = NULL;
|
||||||
m_invalid_requester = TRUE;
|
m_invalid_requester = TRUE;
|
||||||
m_request_locker.Lock();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +346,6 @@ wxSocketInternal::~wxSocketInternal()
|
|||||||
wxASSERT(m_thread_requester == NULL);
|
wxASSERT(m_thread_requester == NULL);
|
||||||
StopWaiter();
|
StopWaiter();
|
||||||
wxASSERT(m_thread_waiter == NULL);
|
wxASSERT(m_thread_waiter == NULL);
|
||||||
m_request_locker.Unlock();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +360,7 @@ SockRequest *wxSocketInternal::WaitForReq()
|
|||||||
|
|
||||||
node = m_requests.First();
|
node = m_requests.First();
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
m_socket_cond.Wait(m_request_locker, 1, 0);
|
m_socket_cond.Wait(m_request_locker, 10, 0);
|
||||||
|
|
||||||
node = m_requests.First();
|
node = m_requests.First();
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
@ -400,44 +406,46 @@ void wxSocketInternal::ResumeRequester()
|
|||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
wxThreadError err;
|
wxThreadError err;
|
||||||
|
|
||||||
wxASSERT(m_thread_requester == NULL);
|
wxASSERT(m_thread_requester == NULL || m_invalid_requester);
|
||||||
|
|
||||||
m_end_requester.Lock();
|
m_end_requester.Lock();
|
||||||
if (m_invalid_requester) {
|
if (m_invalid_requester) {
|
||||||
delete m_thread_requester;
|
if (m_thread_requester != NULL)
|
||||||
|
delete m_thread_requester;
|
||||||
m_thread_requester = new SocketRequester(m_socket, this);
|
|
||||||
m_thread_requester->m_fd = m_socket->m_fd;
|
|
||||||
|
|
||||||
err = m_thread_requester->Create();
|
|
||||||
wxASSERT(err == wxTHREAD_NO_ERROR);
|
|
||||||
|
|
||||||
err = m_thread_requester->Run();
|
|
||||||
wxASSERT(err == wxTHREAD_NO_ERROR);
|
|
||||||
|
|
||||||
m_invalid_requester = FALSE;
|
m_invalid_requester = FALSE;
|
||||||
}
|
}
|
||||||
m_end_requester.Unlock();
|
m_end_requester.Unlock();
|
||||||
|
|
||||||
|
m_thread_requester = new SocketRequester(m_socket, this);
|
||||||
|
|
||||||
|
err = m_thread_requester->Create();
|
||||||
|
wxASSERT(err == wxTHREAD_NO_ERROR);
|
||||||
|
|
||||||
|
err = m_thread_requester->Run();
|
||||||
|
wxASSERT(err == wxTHREAD_NO_ERROR);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxSocketInternal::StopRequester()
|
void wxSocketInternal::StopRequester()
|
||||||
{
|
{
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
|
m_end_requester.Lock();
|
||||||
if (m_invalid_requester) {
|
if (m_invalid_requester) {
|
||||||
|
m_end_requester.Unlock();
|
||||||
delete m_thread_requester;
|
delete m_thread_requester;
|
||||||
m_thread_requester = NULL;
|
m_thread_requester = NULL;
|
||||||
m_invalid_requester = FALSE;
|
m_invalid_requester = FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_end_requester.Unlock();
|
||||||
|
|
||||||
wxASSERT(m_thread_requester != NULL);
|
wxASSERT(m_thread_requester != NULL);
|
||||||
|
|
||||||
m_socket_locker.Lock();
|
m_socket_locker.Lock();
|
||||||
|
|
||||||
// Send a signal to the requester.
|
// Send a signal to the requester.
|
||||||
if (m_requests.Number() == 0)
|
m_socket_cond.Signal();
|
||||||
m_socket_cond.Signal();
|
|
||||||
|
|
||||||
m_socket_locker.Unlock();
|
m_socket_locker.Unlock();
|
||||||
|
|
||||||
@ -458,7 +466,6 @@ void wxSocketInternal::ResumeWaiter()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_thread_waiter = new SocketWaiter(m_socket, this);
|
m_thread_waiter = new SocketWaiter(m_socket, this);
|
||||||
m_thread_waiter->m_fd = m_socket->m_fd;
|
|
||||||
|
|
||||||
err = m_thread_waiter->Create();
|
err = m_thread_waiter->Create();
|
||||||
wxASSERT(err == wxTHREAD_NO_ERROR);
|
wxASSERT(err == wxTHREAD_NO_ERROR);
|
||||||
@ -487,9 +494,14 @@ void wxSocketInternal::StopWaiter()
|
|||||||
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
|
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
|
||||||
{
|
{
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
|
/*
|
||||||
|
if (m_invalid_requester)
|
||||||
|
ResumeRequester();
|
||||||
|
*/
|
||||||
|
m_thread_requester = new SocketRequester(m_socket, this);
|
||||||
|
|
||||||
|
/*
|
||||||
if (async) {
|
if (async) {
|
||||||
if (m_thread_requester == NULL)
|
|
||||||
ResumeRequester();
|
|
||||||
|
|
||||||
m_request_locker.Lock();
|
m_request_locker.Lock();
|
||||||
request->done = FALSE;
|
request->done = FALSE;
|
||||||
@ -510,6 +522,7 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
*/
|
||||||
m_request_locker.Lock();
|
m_request_locker.Lock();
|
||||||
|
|
||||||
if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
|
if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
|
||||||
@ -530,7 +543,9 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
|
|||||||
}
|
}
|
||||||
request->done = TRUE;
|
request->done = TRUE;
|
||||||
m_request_locker.Unlock();
|
m_request_locker.Unlock();
|
||||||
}
|
// }
|
||||||
|
delete m_thread_requester;
|
||||||
|
m_thread_requester = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,6 +736,8 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_internal->SetFD(m_fd);
|
||||||
|
|
||||||
Notify(TRUE);
|
Notify(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,6 +769,8 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock)
|
|||||||
sock.m_fd = fd2;
|
sock.m_fd = fd2;
|
||||||
sock.m_connected = TRUE;
|
sock.m_connected = TRUE;
|
||||||
|
|
||||||
|
sock.m_internal->SetFD(fd2);
|
||||||
|
|
||||||
sock.m_internal->ResumeWaiter();
|
sock.m_internal->ResumeWaiter();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -849,6 +853,8 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
|
|||||||
if (connect(m_fd, remote, len) != 0)
|
if (connect(m_fd, remote, len) != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
m_internal->SetFD(m_fd);
|
||||||
|
|
||||||
// Enables bg events.
|
// Enables bg events.
|
||||||
// ------------------
|
// ------------------
|
||||||
Notify(TRUE);
|
Notify(TRUE);
|
||||||
|
@ -179,7 +179,7 @@ wxWindowBase::~wxWindowBase()
|
|||||||
// we weren't a dialog class
|
// we weren't a dialog class
|
||||||
wxTopLevelWindows.DeleteObject(this);
|
wxTopLevelWindows.DeleteObject(this);
|
||||||
|
|
||||||
wxASSERT_MSG( GetChildren().GetCount() == 0, "children not destroyed" );
|
wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") );
|
||||||
|
|
||||||
if ( m_windowValidator )
|
if ( m_windowValidator )
|
||||||
delete m_windowValidator;
|
delete m_windowValidator;
|
||||||
@ -253,12 +253,12 @@ bool wxWindowBase::DestroyChildren()
|
|||||||
|
|
||||||
wxWindow *child = node->GetData();
|
wxWindow *child = node->GetData();
|
||||||
|
|
||||||
wxASSERT_MSG( child, "children list contains empty nodes" );
|
wxASSERT_MSG( child, _T("children list contains empty nodes") );
|
||||||
|
|
||||||
delete child;
|
delete child;
|
||||||
|
|
||||||
wxASSERT_MSG( !GetChildren().Find(child),
|
wxASSERT_MSG( !GetChildren().Find(child),
|
||||||
"child didn't remove itself using RemoveChild()" );
|
_T("child didn't remove itself using RemoveChild()") );
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -575,7 +575,7 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
|
|||||||
|
|
||||||
void wxWindowBase::MakeModal(bool WXUNUSED(modal))
|
void wxWindowBase::MakeModal(bool WXUNUSED(modal))
|
||||||
{
|
{
|
||||||
wxFAIL_MSG("TODO");
|
wxFAIL_MSG(_T("TODO"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWindowBase::Validate()
|
bool wxWindowBase::Validate()
|
||||||
|
@ -117,12 +117,12 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wxProgressDialog::Update(int value, const char *newmsg)
|
wxProgressDialog::Update(int value, const wxString& newmsg)
|
||||||
{
|
{
|
||||||
wxASSERT(value == -1 || m_gauge);
|
wxASSERT(value == -1 || m_gauge);
|
||||||
if(m_gauge)
|
if(m_gauge)
|
||||||
m_gauge->SetValue(value);
|
m_gauge->SetValue(value);
|
||||||
if(newmsg)
|
if(!newmsg.IsNull())
|
||||||
m_msg->SetLabel(newmsg);
|
m_msg->SetLabel(newmsg);
|
||||||
wxYield();
|
wxYield();
|
||||||
return m_state != Canceled;
|
return m_state != Canceled;
|
||||||
|
@ -305,20 +305,19 @@ void *wxThreadInternal::PthreadStart(void *ptr)
|
|||||||
}
|
}
|
||||||
#if HAVE_THREAD_CLEANUP_FUNCTIONS
|
#if HAVE_THREAD_CLEANUP_FUNCTIONS
|
||||||
// Install the cleanup handler.
|
// Install the cleanup handler.
|
||||||
pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr);
|
// pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// wait for the condition to be signaled from Run()
|
// wait for the condition to be signaled from Run()
|
||||||
// mutex state: currently locked by the thread which created us
|
// mutex state: currently locked by the thread which created us
|
||||||
pthread->m_cond.Wait(pthread->m_mutex);
|
pthread->m_cond.Wait(pthread->m_mutex);
|
||||||
|
|
||||||
// mutex state: locked again on exit of Wait()
|
// mutex state: locked again on exit of Wait()
|
||||||
|
|
||||||
// call the main entry
|
// call the main entry
|
||||||
status = thread->Entry();
|
status = thread->Entry();
|
||||||
|
|
||||||
#if HAVE_THREAD_CLEANUP_FUNCTIONS
|
#if HAVE_THREAD_CLEANUP_FUNCTIONS
|
||||||
pthread_cleanup_pop(FALSE);
|
// pthread_cleanup_pop(FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// terminate the thread
|
// terminate the thread
|
||||||
@ -360,6 +359,9 @@ wxThreadInternal::wxThreadInternal()
|
|||||||
// unlocked in the very end
|
// unlocked in the very end
|
||||||
m_mutex.Lock();
|
m_mutex.Lock();
|
||||||
|
|
||||||
|
// this mutex is used by wxThreadInternal::Wait() and by
|
||||||
|
// wxThreadInternal::SignalExit(). We don't use m_mutex because of a
|
||||||
|
// possible deadlock in either Wait() or SignalExit().
|
||||||
m_end_mutex.Lock();
|
m_end_mutex.Lock();
|
||||||
|
|
||||||
// this mutex is used in Pause()/Resume() and is also locked all the time
|
// this mutex is used in Pause()/Resume() and is also locked all the time
|
||||||
@ -374,6 +376,8 @@ wxThreadInternal::~wxThreadInternal()
|
|||||||
|
|
||||||
// note that m_mutex will be unlocked by the thread which waits for our
|
// note that m_mutex will be unlocked by the thread which waits for our
|
||||||
// termination
|
// termination
|
||||||
|
|
||||||
|
// m_end_mutex can be unlocked here.
|
||||||
m_end_mutex.Unlock();
|
m_end_mutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,16 +410,17 @@ void wxThreadInternal::Wait()
|
|||||||
if ( wxThread::IsMain() )
|
if ( wxThread::IsMain() )
|
||||||
wxMutexGuiLeave();
|
wxMutexGuiLeave();
|
||||||
|
|
||||||
printf("Entering wait ...\n");
|
|
||||||
// entering Wait() releases the mutex thus allowing SignalExit() to acquire
|
// entering Wait() releases the mutex thus allowing SignalExit() to acquire
|
||||||
// it and to signal us its termination
|
// it and to signal us its termination
|
||||||
m_cond.Wait(m_end_mutex);
|
m_cond.Wait(m_end_mutex);
|
||||||
printf("Exiting wait ...\n");
|
|
||||||
|
|
||||||
// mutex is still in the locked state - relocked on exit from Wait(), so
|
// mutex is still in the locked state - relocked on exit from Wait(), so
|
||||||
// unlock it - we don't need it any more, the thread has already terminated
|
// unlock it - we don't need it any more, the thread has already terminated
|
||||||
m_end_mutex.Unlock();
|
m_end_mutex.Unlock();
|
||||||
|
|
||||||
|
// After that, we wait for the real end of the other thread.
|
||||||
|
pthread_join(GetId(), NULL);
|
||||||
|
|
||||||
// reacquire GUI mutex
|
// reacquire GUI mutex
|
||||||
if ( wxThread::IsMain() )
|
if ( wxThread::IsMain() )
|
||||||
wxMutexGuiEnter();
|
wxMutexGuiEnter();
|
||||||
@ -423,21 +428,18 @@ void wxThreadInternal::Wait()
|
|||||||
|
|
||||||
void wxThreadInternal::SignalExit()
|
void wxThreadInternal::SignalExit()
|
||||||
{
|
{
|
||||||
printf("SignalExit\n");
|
|
||||||
// GL: Unlock mutexSuspend here.
|
// GL: Unlock mutexSuspend here.
|
||||||
m_mutexSuspend.Unlock();
|
m_mutexSuspend.Unlock();
|
||||||
|
|
||||||
// as mutex is currently locked, this will block until some other thread
|
// as mutex is currently locked, this will block until some other thread
|
||||||
// (normally the same which created this one) unlocks it by entering Wait()
|
// (normally the same which created this one) unlocks it by entering Wait()
|
||||||
m_end_mutex.Lock();
|
m_end_mutex.Lock();
|
||||||
printf("Mutex acquired\n");
|
|
||||||
|
|
||||||
// wake up all the threads waiting for our termination
|
// wake up all the threads waiting for our termination
|
||||||
m_cond.Broadcast();
|
m_cond.Broadcast();
|
||||||
|
|
||||||
// after this call mutex will be finally unlocked
|
// after this call mutex will be finally unlocked
|
||||||
m_end_mutex.Unlock();
|
m_end_mutex.Unlock();
|
||||||
printf("Mutex unacquired\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxThreadInternal::Pause()
|
void wxThreadInternal::Pause()
|
||||||
@ -664,11 +666,12 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
{
|
{
|
||||||
m_critsect.Enter();
|
m_critsect.Enter();
|
||||||
wxThreadState state = p_internal->GetState();
|
wxThreadState state = p_internal->GetState();
|
||||||
m_critsect.Leave();
|
|
||||||
|
|
||||||
// ask the thread to stop
|
// ask the thread to stop
|
||||||
p_internal->SetCancelFlag();
|
p_internal->SetCancelFlag();
|
||||||
|
|
||||||
|
m_critsect.Leave();
|
||||||
|
|
||||||
switch ( state )
|
switch ( state )
|
||||||
{
|
{
|
||||||
case STATE_NEW:
|
case STATE_NEW:
|
||||||
@ -716,20 +719,16 @@ void wxThread::Exit(void *status)
|
|||||||
{
|
{
|
||||||
// first call user-level clean up code
|
// first call user-level clean up code
|
||||||
OnExit();
|
OnExit();
|
||||||
printf(" ... OnExit()\n");
|
|
||||||
|
|
||||||
// next wake up the threads waiting for us (OTOH, this function won't return
|
// next wake up the threads waiting for us (OTOH, this function won't return
|
||||||
// until someone waited for us!)
|
// until someone waited for us!)
|
||||||
p_internal->SignalExit();
|
p_internal->SignalExit();
|
||||||
printf(" ... SignalExit()\n");
|
|
||||||
|
|
||||||
p_internal->SetState(STATE_EXITED);
|
p_internal->SetState(STATE_EXITED);
|
||||||
printf(" ... SetState()\n");
|
|
||||||
|
|
||||||
// delete both C++ thread object and terminate the OS thread object
|
// delete both C++ thread object and terminate the OS thread object
|
||||||
// GL: This is very ugly and buggy ...
|
// GL: This is very ugly and buggy ...
|
||||||
// delete this;
|
// delete this;
|
||||||
printf(" ... Exit\n");
|
|
||||||
pthread_exit(status);
|
pthread_exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user