* 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
@param newmsg if used, new message to display
@returns true if ABORT button has not been pressed
*/
@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
/** 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
void ReleaseFD();
int GetFD() { return m_fd; }
void ReleaseFD();
int GetFD() { return m_fd; }
+ void SetFD(int fd) { m_fd = fd; }
void ResumeWaiter();
void StopWaiter();
void ResumeWaiter();
void StopWaiter();
wxSocketHandler::Master();
sock = new MyClient();
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);
wxSocketHandler::Master().Register(sock);
sock->frame = this;
sock->SetNotify(wxSocketBase::REQ_LOST);
if (sock->IsConnected())
sock->Close();
if (sock->IsConnected())
sock->Close();
wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server",
"Connect ...", "localhost");
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);
addr.Hostname(hname);
addr.Service(3000);
sock->SetNotify(0);
if (sock2 == NULL)
return;
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);
sock2->Notify(TRUE);
sock2->SetEventHandler(*this, SKDEMO_SOCKET);
server->SetNotify(wxSocketBase::REQ_ACCEPT);
wxSocketHandler::Master().Register(sock);
sock->SetNotify(wxSocketBase::REQ_ACCEPT);
sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
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;
sock->Notify(TRUE);
nb_clients = 0;
/* Define if you have all functions to set thread priority */
#undef HAVE_THREAD_PRIORITY_FUNCTIONS
/* 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
/* Define if your system has its own `getloadavg' function. */
#undef HAVE_GETLOADAVG
wxEvent *event_main;
wxCriticalSectionLocker locker(*m_eventsLocker);
wxEvent *event_main;
wxCriticalSectionLocker locker(*m_eventsLocker);
// check that we are really in a child thread
wxASSERT( !wxThread::IsMain() );
// check that we are really in a child thread
wxASSERT( !wxThread::IsMain() );
wxPendingEventsLocker->Leave();
#ifdef __WXGTK__
wxPendingEventsLocker->Leave();
#ifdef __WXGTK__
- if (g_isIdle) wxapp_install_idle_handler();
+// if (g_isIdle) wxapp_install_idle_handler();
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-// 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
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
// RCS_ID: $Id$
// License: see wxWindows license
#if wxUSE_THREADS
SocketWaiter::SocketWaiter(wxSocketBase *socket,
wxSocketInternal *internal)
#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())
// Else, no error => there is something to be read else
// we've lost the connection.
// Else, no error => there is something to be read else
// we've lost the connection.
m_socket->OnRequest(wxSocketBase::EVT_READ);
m_socket->OnRequest(wxSocketBase::EVT_READ);
m_socket->OnRequest(wxSocketBase::EVT_LOST);
Exit(NULL);
}
m_socket->OnRequest(wxSocketBase::EVT_LOST);
Exit(NULL);
}
FD_ZERO(&sockrd_set);
FD_ZERO(&sockwr_set);
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();
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))
m_internal->ReleaseFD();
if (FD_ISSET(m_fd, &sockrd_set))
SocketRequester::SocketRequester(wxSocketBase *socket,
wxSocketInternal *internal)
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())
FD_SET(m_fd, &sockwr_set);
m_internal->AcquireFD();
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);
m_internal->ReleaseFD();
return (ret != 0);
+ 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();
m_internal->AcquireFD();
ret = send(m_fd, req->buffer, req->size, 0);
m_internal->ReleaseFD();
+ 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();
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) {
m_internal->m_invalid_requester = TRUE;
m_internal->m_end_requester.Unlock();
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();
return NULL;
}
m_internal->m_end_requester.Unlock();
m_thread_requester = NULL;
m_thread_waiter = NULL;
m_invalid_requester = TRUE;
m_thread_requester = NULL;
m_thread_waiter = NULL;
m_invalid_requester = TRUE;
- m_request_locker.Lock();
wxASSERT(m_thread_requester == NULL);
StopWaiter();
wxASSERT(m_thread_waiter == NULL);
wxASSERT(m_thread_requester == NULL);
StopWaiter();
wxASSERT(m_thread_waiter == NULL);
- m_request_locker.Unlock();
node = m_requests.First();
if (node == NULL) {
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)
node = m_requests.First();
if (node == NULL)
#if wxUSE_THREADS
wxThreadError err;
#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) {
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
#endif
}
void wxSocketInternal::StopRequester()
{
#if wxUSE_THREADS
+ m_end_requester.Lock();
if (m_invalid_requester) {
if (m_invalid_requester) {
+ m_end_requester.Unlock();
delete m_thread_requester;
m_thread_requester = NULL;
m_invalid_requester = FALSE;
return;
}
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.
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();
m_socket_locker.Unlock();
return;
m_thread_waiter = new SocketWaiter(m_socket, this);
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);
err = m_thread_waiter->Create();
wxASSERT(err == wxTHREAD_NO_ERROR);
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
{
#if wxUSE_THREADS
void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
{
#if wxUSE_THREADS
+/*
+ if (m_invalid_requester)
+ ResumeRequester();
+*/
+ m_thread_requester = new SocketRequester(m_socket, this);
+
+/*
- if (m_thread_requester == NULL)
- ResumeRequester();
m_request_locker.Lock();
request->done = FALSE;
m_request_locker.Lock();
request->done = FALSE;
m_request_locker.Lock();
if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
m_request_locker.Lock();
if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
}
request->done = TRUE;
m_request_locker.Unlock();
}
request->done = TRUE;
m_request_locker.Unlock();
+// }
+ delete m_thread_requester;
+ m_thread_requester = NULL;
+ m_internal->SetFD(m_fd);
+
sock.m_fd = fd2;
sock.m_connected = TRUE;
sock.m_fd = fd2;
sock.m_connected = TRUE;
+ sock.m_internal->SetFD(fd2);
+
sock.m_internal->ResumeWaiter();
return TRUE;
sock.m_internal->ResumeWaiter();
return TRUE;
if (connect(m_fd, remote, len) != 0)
return FALSE;
if (connect(m_fd, remote, len) != 0)
return FALSE;
+ m_internal->SetFD(m_fd);
+
// Enables bg events.
// ------------------
Notify(TRUE);
// Enables bg events.
// ------------------
Notify(TRUE);
// we weren't a dialog class
wxTopLevelWindows.DeleteObject(this);
// 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;
if ( m_windowValidator )
delete m_windowValidator;
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;
wxASSERT_MSG( !GetChildren().Find(child),
delete child;
wxASSERT_MSG( !GetChildren().Find(child),
- "child didn't remove itself using RemoveChild()" );
+ _T("child didn't remove itself using RemoveChild()") );
void wxWindowBase::MakeModal(bool WXUNUSED(modal))
{
void wxWindowBase::MakeModal(bool WXUNUSED(modal))
{
+ wxFAIL_MSG(_T("TODO"));
}
bool wxWindowBase::Validate()
}
bool wxWindowBase::Validate()
-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);
{
wxASSERT(value == -1 || m_gauge);
if(m_gauge)
m_gauge->SetValue(value);
m_msg->SetLabel(newmsg);
wxYield();
return m_state != Canceled;
m_msg->SetLabel(newmsg);
wxYield();
return m_state != Canceled;
}
#if HAVE_THREAD_CLEANUP_FUNCTIONS
// Install the cleanup handler.
}
#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);
#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
// 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
#endif
// terminate the thread
// unlocked in the very end
m_mutex.Lock();
// 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
m_end_mutex.Lock();
// this mutex is used in Pause()/Resume() and is also locked all the time
// note that m_mutex will be unlocked by the thread which waits for our
// termination
// note that m_mutex will be unlocked by the thread which waits for our
// termination
+
+ // m_end_mutex can be unlocked here.
if ( wxThread::IsMain() )
wxMutexGuiLeave();
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);
// 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();
// 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();
// reacquire GUI mutex
if ( wxThread::IsMain() )
wxMutexGuiEnter();
void wxThreadInternal::SignalExit()
{
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();
// 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();
// 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()
}
void wxThreadInternal::Pause()
{
m_critsect.Enter();
wxThreadState state = p_internal->GetState();
{
m_critsect.Enter();
wxThreadState state = p_internal->GetState();
// ask the thread to stop
p_internal->SetCancelFlag();
// ask the thread to stop
p_internal->SetCancelFlag();
switch ( state )
{
case STATE_NEW:
switch ( state )
{
case STATE_NEW:
{
// first call user-level clean up code
OnExit();
{
// 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();
// 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);
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;
// delete both C++ thread object and terminate the OS thread object
// GL: This is very ugly and buggy ...
// delete this;