From: Guilhem Lavaux Date: Mon, 17 May 1999 18:10:57 +0000 (+0000) Subject: * prgodlgg.h: Update() use wxString instead of 'char *' X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9111db680241332df07dd22db32973e20f77fb1a * 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 --- diff --git a/include/wx/generic/progdlgg.h b/include/wx/generic/progdlgg.h index 2401275d14..27b5fffe4f 100644 --- a/include/wx/generic/progdlgg.h +++ b/include/wx/generic/progdlgg.h @@ -53,7 +53,7 @@ public: @param newmsg if used, new message to display @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 the program decided to continue the operation (e.g., user didn't diff --git a/include/wx/sckint.h b/include/wx/sckint.h index 8d90c4b133..0a3ca5b5e5 100644 --- a/include/wx/sckint.h +++ b/include/wx/sckint.h @@ -118,6 +118,7 @@ class wxSocketInternal { void ReleaseFD(); int GetFD() { return m_fd; } + void SetFD(int fd) { m_fd = fd; } void ResumeWaiter(); void StopWaiter(); diff --git a/samples/wxsocket/client.cpp b/samples/wxsocket/client.cpp index bbda2d7525..ffb17c4de8 100644 --- a/samples/wxsocket/client.cpp +++ b/samples/wxsocket/client.cpp @@ -137,7 +137,7 @@ MyFrame::MyFrame(): wxSocketHandler::Master(); sock = new MyClient(); - sock->SetFlags(wxSocketBase::WAITALL); + sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED)); wxSocketHandler::Master().Register(sock); sock->frame = this; sock->SetNotify(wxSocketBase::REQ_LOST); @@ -162,8 +162,11 @@ void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt)) if (sock->IsConnected()) sock->Close(); +/* wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server", "Connect ...", "localhost"); +*/ + wxString hname = "localhost"; addr.Hostname(hname); addr.Service(3000); sock->SetNotify(0); diff --git a/samples/wxsocket/server.cpp b/samples/wxsocket/server.cpp index 45825d88fb..727c8e63a8 100644 --- a/samples/wxsocket/server.cpp +++ b/samples/wxsocket/server.cpp @@ -132,7 +132,7 @@ void MyFrame::OnSockRequestServer(wxSocketEvent& evt) if (sock2 == NULL) return; - sock2->SetFlags(wxSocketBase::NONE); + sock2->SetFlags(wxSocketBase::SPEED); sock2->Notify(TRUE); sock2->SetEventHandler(*this, SKDEMO_SOCKET); server->SetNotify(wxSocketBase::REQ_ACCEPT); @@ -154,6 +154,7 @@ MyFrame::MyFrame(wxFrame *frame): wxSocketHandler::Master().Register(sock); sock->SetNotify(wxSocketBase::REQ_ACCEPT); sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV); + sock->SetFlags(wxSocketBase::SPEED); sock->Notify(TRUE); nb_clients = 0; diff --git a/setup/setup.hin b/setup/setup.hin index 8af73a69d9..5a7f96a985 100644 --- a/setup/setup.hin +++ b/setup/setup.hin @@ -440,6 +440,9 @@ /* Define if you have all functions to set thread priority */ #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. */ #undef HAVE_GETLOADAVG diff --git a/src/common/event.cpp b/src/common/event.cpp index 00c121814f..3db1b841b3 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -527,7 +527,6 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event) wxEvent *event_main; wxCriticalSectionLocker locker(*m_eventsLocker); - // check that we are really in a child thread wxASSERT( !wxThread::IsMain() ); @@ -543,7 +542,7 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event) wxPendingEventsLocker->Leave(); #ifdef __WXGTK__ - if (g_isIdle) wxapp_install_idle_handler(); +// if (g_isIdle) wxapp_install_idle_handler(); #endif return TRUE; diff --git a/src/common/sckint.cpp b/src/common/sckint.cpp index de4284bd35..925ffebf7a 100644 --- a/src/common/sckint.cpp +++ b/src/common/sckint.cpp @@ -1,10 +1,9 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: socket.cpp -// Purpose: Socket handler classes -// Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew -// Davidson(1995) in wxWeb) -// Created: April 1997 -// Updated: April 1999 +// Name: sckint.cpp +// Purpose: Socket internal classes +// Authors: Guilhem Lavaux +// Created: April 1999 +// Updated: // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux // RCS_ID: $Id$ // License: see wxWindows license @@ -87,7 +86,8 @@ #if wxUSE_THREADS SocketWaiter::SocketWaiter(wxSocketBase *socket, 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 // we've lost the connection. - if (ret > 0) + if (ret > 0) { m_socket->OnRequest(wxSocketBase::EVT_READ); - else { + } else { m_socket->OnRequest(wxSocketBase::EVT_LOST); Exit(NULL); } @@ -140,14 +140,14 @@ void *SocketWaiter::Entry() FD_ZERO(&sockrd_set); FD_ZERO(&sockwr_set); - + if ((m_socket->NeededReq() & READ_MASK) != 0) FD_SET(m_fd, &sockrd_set); if ((m_socket->NeededReq() & WRITE_MASK) != 0) FD_SET(m_fd, &sockwr_set); 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(); if (FD_ISSET(m_fd, &sockrd_set)) @@ -180,7 +180,8 @@ void *SocketWaiter::Entry() SocketRequester::SocketRequester(wxSocketBase *socket, 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); 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(); return (ret != 0); @@ -253,6 +254,11 @@ void SocketRequester::ProcessWriteEvent(SockRequest *req) int ret; size_t len; + if (!WaitFor(wxSocketBase::REQ_WRITE, req->timeout)) { + m_internal->EndRequest(req); + return; + } + m_internal->AcquireFD(); ret = send(m_fd, req->buffer, req->size, 0); m_internal->ReleaseFD(); @@ -287,13 +293,15 @@ void *SocketRequester::Entry() { SockRequest *req; + m_internal->m_request_locker.Lock(); while (1) { // Wait for a new request or a destroy message. req = m_internal->WaitForReq(); m_internal->m_end_requester.Lock(); - if (TestDestroy() || req == NULL) { + if (req == NULL) { m_internal->m_invalid_requester = TRUE; m_internal->m_end_requester.Unlock(); + m_internal->m_request_locker.Unlock(); return NULL; } m_internal->m_end_requester.Unlock(); @@ -328,7 +336,6 @@ wxSocketInternal::wxSocketInternal(wxSocketBase *socket) m_thread_requester = NULL; m_thread_waiter = NULL; m_invalid_requester = TRUE; - m_request_locker.Lock(); #endif } @@ -339,7 +346,6 @@ wxSocketInternal::~wxSocketInternal() wxASSERT(m_thread_requester == NULL); StopWaiter(); wxASSERT(m_thread_waiter == NULL); - m_request_locker.Unlock(); #endif } @@ -354,7 +360,7 @@ SockRequest *wxSocketInternal::WaitForReq() node = m_requests.First(); 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(); if (node == NULL) @@ -400,44 +406,46 @@ void wxSocketInternal::ResumeRequester() #if wxUSE_THREADS wxThreadError err; - wxASSERT(m_thread_requester == NULL); + wxASSERT(m_thread_requester == NULL || m_invalid_requester); m_end_requester.Lock(); if (m_invalid_requester) { - delete m_thread_requester; + if (m_thread_requester != NULL) + delete m_thread_requester; + m_invalid_requester = FALSE; + } + m_end_requester.Unlock(); - m_thread_requester = new SocketRequester(m_socket, this); - m_thread_requester->m_fd = m_socket->m_fd; + m_thread_requester = new SocketRequester(m_socket, this); - err = m_thread_requester->Create(); - wxASSERT(err == wxTHREAD_NO_ERROR); + err = m_thread_requester->Create(); + 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); - m_invalid_requester = FALSE; - } - m_end_requester.Unlock(); #endif } void wxSocketInternal::StopRequester() { #if wxUSE_THREADS + m_end_requester.Lock(); if (m_invalid_requester) { + m_end_requester.Unlock(); delete m_thread_requester; m_thread_requester = NULL; m_invalid_requester = FALSE; return; } + m_end_requester.Unlock(); 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_cond.Signal(); m_socket_locker.Unlock(); @@ -458,7 +466,6 @@ void wxSocketInternal::ResumeWaiter() return; 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); @@ -487,9 +494,14 @@ void wxSocketInternal::StopWaiter() void wxSocketInternal::QueueRequest(SockRequest *request, bool async) { #if wxUSE_THREADS +/* + if (m_invalid_requester) + ResumeRequester(); +*/ + m_thread_requester = new SocketRequester(m_socket, this); + +/* if (async) { - if (m_thread_requester == NULL) - ResumeRequester(); m_request_locker.Lock(); request->done = FALSE; @@ -510,6 +522,7 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async) } } } else { +*/ m_request_locker.Lock(); if ((request->type & wxSocketBase::REQ_WAIT) != 0) { @@ -530,7 +543,9 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async) } request->done = TRUE; m_request_locker.Unlock(); - } +// } + delete m_thread_requester; + m_thread_requester = NULL; #endif } diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 2372865175..bbfdb4e5d2 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -736,6 +736,8 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man, return; } + m_internal->SetFD(m_fd); + Notify(TRUE); } @@ -767,6 +769,8 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock) sock.m_fd = fd2; sock.m_connected = TRUE; + sock.m_internal->SetFD(fd2); + sock.m_internal->ResumeWaiter(); return TRUE; @@ -849,6 +853,8 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) ) if (connect(m_fd, remote, len) != 0) return FALSE; + m_internal->SetFD(m_fd); + // Enables bg events. // ------------------ Notify(TRUE); diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 2fead4a77e..ac18d99f86 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -179,7 +179,7 @@ wxWindowBase::~wxWindowBase() // we weren't a dialog class wxTopLevelWindows.DeleteObject(this); - wxASSERT_MSG( GetChildren().GetCount() == 0, "children not destroyed" ); + wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") ); if ( m_windowValidator ) delete m_windowValidator; @@ -253,12 +253,12 @@ bool wxWindowBase::DestroyChildren() wxWindow *child = node->GetData(); - wxASSERT_MSG( child, "children list contains empty nodes" ); + wxASSERT_MSG( child, _T("children list contains empty nodes") ); delete child; wxASSERT_MSG( !GetChildren().Find(child), - "child didn't remove itself using RemoveChild()" ); + _T("child didn't remove itself using RemoveChild()") ); } return TRUE; @@ -575,7 +575,7 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name ) void wxWindowBase::MakeModal(bool WXUNUSED(modal)) { - wxFAIL_MSG("TODO"); + wxFAIL_MSG(_T("TODO")); } bool wxWindowBase::Validate() diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index c156b612b0..c43494211f 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -117,12 +117,12 @@ wxProgressDialog::wxProgressDialog(wxString const &title, bool -wxProgressDialog::Update(int value, const char *newmsg) +wxProgressDialog::Update(int value, const wxString& newmsg) { wxASSERT(value == -1 || m_gauge); if(m_gauge) m_gauge->SetValue(value); - if(newmsg) + if(!newmsg.IsNull()) m_msg->SetLabel(newmsg); wxYield(); return m_state != Canceled; diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index 8548b18014..a1764a30c3 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -305,20 +305,19 @@ void *wxThreadInternal::PthreadStart(void *ptr) } #if HAVE_THREAD_CLEANUP_FUNCTIONS // Install the cleanup handler. - pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr); +// pthread_cleanup_push(wxThreadInternal::PthreadCleanup, ptr); #endif // wait for the condition to be signaled from Run() // mutex state: currently locked by the thread which created us pthread->m_cond.Wait(pthread->m_mutex); - // mutex state: locked again on exit of Wait() // call the main entry status = thread->Entry(); #if HAVE_THREAD_CLEANUP_FUNCTIONS - pthread_cleanup_pop(FALSE); +// pthread_cleanup_pop(FALSE); #endif // terminate the thread @@ -360,6 +359,9 @@ wxThreadInternal::wxThreadInternal() // unlocked in the very end 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(); // 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 // termination + + // m_end_mutex can be unlocked here. m_end_mutex.Unlock(); } @@ -406,16 +410,17 @@ void wxThreadInternal::Wait() if ( wxThread::IsMain() ) wxMutexGuiLeave(); - printf("Entering wait ...\n"); // entering Wait() releases the mutex thus allowing SignalExit() to acquire // it and to signal us its termination m_cond.Wait(m_end_mutex); - printf("Exiting wait ...\n"); // 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 m_end_mutex.Unlock(); + // After that, we wait for the real end of the other thread. + pthread_join(GetId(), NULL); + // reacquire GUI mutex if ( wxThread::IsMain() ) wxMutexGuiEnter(); @@ -423,21 +428,18 @@ void wxThreadInternal::Wait() void wxThreadInternal::SignalExit() { - printf("SignalExit\n"); // GL: Unlock mutexSuspend here. m_mutexSuspend.Unlock(); // as mutex is currently locked, this will block until some other thread // (normally the same which created this one) unlocks it by entering Wait() m_end_mutex.Lock(); - printf("Mutex acquired\n"); // wake up all the threads waiting for our termination m_cond.Broadcast(); // after this call mutex will be finally unlocked m_end_mutex.Unlock(); - printf("Mutex unacquired\n"); } void wxThreadInternal::Pause() @@ -664,11 +666,12 @@ wxThread::ExitCode wxThread::Delete() { m_critsect.Enter(); wxThreadState state = p_internal->GetState(); - m_critsect.Leave(); // ask the thread to stop p_internal->SetCancelFlag(); + m_critsect.Leave(); + switch ( state ) { case STATE_NEW: @@ -716,20 +719,16 @@ void wxThread::Exit(void *status) { // first call user-level clean up code OnExit(); - printf(" ... OnExit()\n"); // next wake up the threads waiting for us (OTOH, this function won't return // until someone waited for us!) p_internal->SignalExit(); - printf(" ... SignalExit()\n"); p_internal->SetState(STATE_EXITED); - printf(" ... SetState()\n"); // delete both C++ thread object and terminate the OS thread object // GL: This is very ugly and buggy ... // delete this; - printf(" ... Exit\n"); pthread_exit(status); }