* 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:
Guilhem Lavaux 1999-05-17 18:10:57 +00:00
parent 49828363f8
commit 9111db6802
11 changed files with 86 additions and 59 deletions

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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
} }

View File

@ -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);

View File

@ -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()

View File

@ -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;

View File

@ -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);
} }