From aadbdf11bda695e2ca135ef1e4dc09d6c01d2521 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Fri, 7 May 1999 18:34:32 +0000 Subject: [PATCH] * Created a new wxObject method: wxObject::CopyObject(wxObject&) and wxObject::Clone() uses it. * Added some CopyObject to events. * Reenable the idle loop in wxEvtHandler::ProcessThreadEvent(...) * Some correctness in wxSocket. Major bugs remaining: - it seems there is a mutex problem when it works too quickly - all threads aren't destroyed ... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2358 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/event.h | 29 +++++++-- include/wx/object.h | 3 +- include/wx/socket.h | 3 +- src/common/event.cpp | 144 ++++++++++++++++++++++++++++++++++++++---- src/common/object.cpp | 9 ++- src/common/sckint.cpp | 65 ++++++++++--------- src/common/socket.cpp | 19 ++++-- src/msw/app.cpp | 13 ++-- 8 files changed, 220 insertions(+), 65 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index 61e6cec495..6bd1e2f7ff 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -290,7 +290,7 @@ public: // exists only for optimization purposes bool IsCommandEvent() const { return m_isCommandEvent; } - wxObject *Clone() const; + void CopyObject(wxObject& object_dest) const; public: bool m_skipped; @@ -366,6 +366,8 @@ public: void SetInt(int i) { m_commandInt = i; } long GetInt() const { return m_commandInt ; } + void CopyObject(wxObject& obj) const; + public: wxString m_commandString; // String event argument int m_commandInt; @@ -545,6 +547,8 @@ public: // Get Y position long GetY() const { return m_y; } + void CopyObject(wxObject& obj) const; + public: long m_x; long m_y; @@ -594,6 +598,8 @@ public: // Get Y position long GetY() const { return m_y; } + void CopyObject(wxObject& obj) const; + public: long m_x; long m_y; @@ -622,6 +628,8 @@ public: { m_eventType = wxEVT_SIZE; m_id = id; } wxSize GetSize() const { return m_size; } + + void CopyObject(wxObject& obj) const; }; // Move event class @@ -643,6 +651,8 @@ public: { m_eventType = wxEVT_MOVE; m_id = id; } wxPoint GetPosition() const { return m_pos; } + + void CopyObject(wxObject& obj) const; }; // Paint event class @@ -676,6 +686,8 @@ public: wxEraseEvent(int Id = 0, wxDC *dc = (wxDC *) NULL) { m_eventType = wxEVT_ERASE_BACKGROUND; m_id = Id; m_dc = dc; } wxDC *GetDC() const { return m_dc; } + + void CopyObject(wxObject& obj) const; }; // Focus event class @@ -708,6 +720,8 @@ public: { m_eventType = type; m_active = active; m_id = Id; } bool GetActive() const { return m_active; } + void CopyObject(wxObject& obj) const; + private: bool m_active; }; @@ -740,13 +754,14 @@ class WXDLLEXPORT wxMenuEvent : public wxEvent DECLARE_DYNAMIC_CLASS(wxMenuEvent) public: - wxMenuEvent(wxEventType type = wxEVT_NULL, int id = 0) - { m_eventType = type; m_menuId = id; } + wxMenuEvent(wxEventType type = wxEVT_NULL, int id = 0) + { m_eventType = type; m_menuId = id; } - int GetMenuId() const { return m_menuId; } + int GetMenuId() const { return m_menuId; } + void CopyObject(wxObject& obj) const; private: - int m_menuId; + int m_menuId; }; // Window close or session close event class @@ -797,6 +812,8 @@ public: bool GetForce() const { return m_force; } #endif + void CopyObject(wxObject& obj) const; + protected: bool m_loggingOff; bool m_veto, m_canVeto; @@ -822,6 +839,8 @@ public: void SetShow(bool show) { m_show = show; } bool GetShow() const { return m_show; } + void CopyObject(wxObject& obj) const; + protected: bool m_show; }; diff --git a/include/wx/object.h b/include/wx/object.h index c98a826e98..61c34c41ec 100644 --- a/include/wx/object.h +++ b/include/wx/object.h @@ -192,7 +192,8 @@ class WXDLLEXPORT wxObject virtual ~wxObject(void); virtual wxClassInfo *GetClassInfo(void) const { return &sm_classwxObject; } - virtual wxObject *Clone(void) const; + wxObject *Clone(void) const; + virtual void CopyObject(wxObject& object_dest) const; bool IsKindOf(wxClassInfo *info) const; diff --git a/include/wx/socket.h b/include/wx/socket.h index 21cd4cba90..a8161406c8 100644 --- a/include/wx/socket.h +++ b/include/wx/socket.h @@ -262,7 +262,8 @@ public: wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; } wxSocketBase *Socket() const { return m_socket; } - wxObject *Clone() const; + void CopyObject(wxObject& obj_d) const; + public: wxSocketBase::wxRequestEvent m_skevt; wxSocketBase *m_socket; diff --git a/src/common/event.cpp b/src/common/event.cpp index b0de8f2df3..0b831bb6a9 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -98,20 +98,19 @@ wxEvent::wxEvent(int theId) m_isCommandEvent = FALSE; } -wxObject *wxEvent::Clone() const +void wxEvent::CopyObject(wxObject& object_dest) const { - wxEvent *event = (wxEvent *)wxObject::Clone(); + wxEvent *obj = (wxEvent *)&object_dest; + wxObject::CopyObject(object_dest); - event->m_eventType = m_eventType; - event->m_eventObject = m_eventObject; - event->m_eventHandle = m_eventHandle; - event->m_timeStamp = m_timeStamp; - event->m_id = m_id; - event->m_skipped = m_skipped; - event->m_callbackUserData = m_callbackUserData; - event->m_isCommandEvent = m_isCommandEvent; - - return event; + obj->m_eventType = m_eventType; + obj->m_eventObject = m_eventObject; + obj->m_eventHandle = m_eventHandle; + obj->m_timeStamp = m_timeStamp; + obj->m_id = m_id; + obj->m_skipped = m_skipped; + obj->m_callbackUserData = m_callbackUserData; + obj->m_isCommandEvent = m_isCommandEvent; } /* @@ -131,6 +130,18 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId) m_isCommandEvent = TRUE; } +void wxCommandEvent::CopyObject(wxObject& obj_d) const +{ + wxCommandEvent *obj = (wxCommandEvent *)&obj_d; + + wxEvent::CopyObject(obj_d); + + obj->m_clientData = m_clientData; + obj->m_clientObject = m_clientObject; + obj->m_extraLong = m_extraLong; + obj->m_commandInt = m_commandInt; +} + /* * Scroll events */ @@ -145,7 +156,6 @@ wxScrollEvent::wxScrollEvent(wxEventType commandType, m_commandInt = pos; } - /* * Mouse events * @@ -165,6 +175,23 @@ wxMouseEvent::wxMouseEvent(wxEventType commandType) m_y = 0; } +void wxMouseEvent::CopyObject(wxObject& obj_d) const +{ + wxMouseEvent *obj = (wxMouseEvent *)&obj_d; + + wxEvent::CopyObject(obj_d); + + obj->m_metaDown = m_metaDown; + obj->m_altDown = m_altDown; + obj->m_controlDown = m_controlDown; + obj->m_shiftDown = m_shiftDown; + obj->m_leftDown = m_leftDown; + obj->m_rightDown = m_rightDown; + obj->m_middleDown = m_middleDown; + obj->m_x = m_x; + obj->m_y = m_y; +} + // True if was a button dclick event (1 = left, 2 = middle, 3 = right) // or any button dclick event (but = -1) bool wxMouseEvent::ButtonDClick(int but) const @@ -287,6 +314,85 @@ wxKeyEvent::wxKeyEvent(wxEventType type) m_keyCode = 0; } +void wxKeyEvent::CopyObject(wxObject& obj_d) const +{ + wxKeyEvent *obj = (wxKeyEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_shiftDown = m_shiftDown; + obj->m_controlDown = m_controlDown; + obj->m_metaDown = m_metaDown; + obj->m_altDown = m_altDown; + obj->m_keyCode = m_keyCode; +} + + +/* + * Misc events + */ + +void wxSizeEvent::CopyObject(wxObject& obj_d) const +{ + wxSizeEvent *obj = (wxSizeEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_size = m_size; +} + +void wxMoveEvent::CopyObject(wxObject& obj_d) const +{ + wxMoveEvent *obj = (wxMoveEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_pos = m_pos; +} + +void wxEraseEvent::CopyObject(wxObject& obj_d) const +{ + wxEraseEvent *obj = (wxEraseEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_dc = m_dc; +} + +void wxActivateEvent::CopyObject(wxObject& obj_d) const +{ + wxActivateEvent *obj = (wxActivateEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_active = m_active; +} + +void wxMenuEvent::CopyObject(wxObject& obj_d) const +{ + wxMenuEvent *obj = (wxMenuEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_menuId = m_menuId; +} + +void wxCloseEvent::CopyObject(wxObject& obj_d) const +{ + wxCloseEvent *obj = (wxCloseEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_loggingOff = m_loggingOff; + obj->m_veto = m_veto; +#if WXWIN_COMPATIBILITY + obj->m_force = m_force; +#endif + obj->m_canVeto = m_canVeto; +} + +void wxShowEvent::CopyObject(wxObject& obj_d) const +{ + wxShowEvent *obj = (wxShowEvent *)&obj_d; + wxEvent::CopyObject(obj_d); + + obj->m_show = m_show; +} + + /* * Event handler */ @@ -335,11 +441,19 @@ wxEvtHandler::~wxEvtHandler() } #if wxUSE_THREADS + +#ifdef __WXGTK__ +extern bool g_isIdle; + +extern void wxapp_install_idle_handler(); +#endif + bool wxEvtHandler::ProcessThreadEvent(wxEvent& event) { wxEvent *event_main; wxCriticalSectionLocker locker(*m_eventsLocker); + // check that we are really in a child thread wxASSERT( !wxThread::IsMain() ); @@ -354,6 +468,10 @@ bool wxEvtHandler::ProcessThreadEvent(wxEvent& event) wxPendingEvents->Append(this); wxPendingEventsLocker->Leave(); +#ifdef __WXGTK__ + if (g_isIdle) wxapp_install_idle_handler(); +#endif + return TRUE; } diff --git a/src/common/object.cpp b/src/common/object.cpp index 5b65936689..dbc9d46ef4 100644 --- a/src/common/object.cpp +++ b/src/common/object.cpp @@ -89,7 +89,14 @@ bool wxObject::IsKindOf(wxClassInfo *info) const wxObject *wxObject::Clone() const { - return GetClassInfo()->CreateObject(); + wxObject *object = GetClassInfo()->CreateObject(); + CopyObject(*object); + return object; +} + +void wxObject::CopyObject(wxObject& object_dest) const +{ + wxASSERT(object_dest.GetClassInfo()->IsKindOf(GetClassInfo())); } #if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT diff --git a/src/common/sckint.cpp b/src/common/sckint.cpp index a8699b5859..a177aed788 100644 --- a/src/common/sckint.cpp +++ b/src/common/sckint.cpp @@ -159,19 +159,15 @@ void *SocketWaiter::Entry() #ifdef Yield #undef Yield #endif +#endif - if (ret == 0) - // If nothing happened, we wait for 100 ms. - wxThread::Sleep(10); - else - wxThread::Yield(); -#else +/* if (ret == 0) // If nothing happened, we wait for 100 ms. wxUsleep(10); else wxYield(); -#endif +*/ // Check whether we should exit. if (TestDestroy()) @@ -331,7 +327,6 @@ wxSocketInternal::wxSocketInternal(wxSocketBase *socket) wxSocketInternal::~wxSocketInternal() { -// wxASSERT(!m_finalized); there is no m_finalized anywhere, RR m_request_locker.Unlock(); delete m_thread_waiter; delete m_thread_requester; @@ -387,8 +382,8 @@ void wxSocketInternal::ReleaseFD() // ---------------------------------------------------------------------- void wxSocketInternal::InitializeSocket() { -// wxASSERT( ((m_thread_waiter->IsAlive() && !m_thread_waiter->IsPaused()) || -// (m_thread_requester->IsAlive() && !m_thread_requester->IsPaused()))); + 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; @@ -396,19 +391,17 @@ void wxSocketInternal::InitializeSocket() if (m_thread_waiter->IsPaused()) ResumeSocket(); else { + wxThreadError err; - if (m_thread_waiter->Create() != wxTHREAD_NO_ERROR) { - // Something should be done here. - return; - } - - if (m_thread_requester->Create() != wxTHREAD_NO_ERROR) { - // Something should be done here. - return; - } - - m_thread_waiter->Run(); - m_thread_requester->Run(); + err = m_thread_waiter->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); } } @@ -418,41 +411,47 @@ void wxSocketInternal::InitializeSocket() // ---------------------------------------------------------------------- void wxSocketInternal::FinalizeSocket() { - wxASSERT( (!m_thread_waiter->IsAlive() && !m_thread_requester->IsAlive()) ); - ResumeSocket(); m_thread_waiter->Delete(); + + // Send a signal to the thread "requester". + m_socket_locker.Lock(); if (m_requests.Number() == 0) m_socket_cond.Signal(); m_socket_locker.Unlock(); + // Finish the destruction of the thread "requester". m_thread_requester->Delete(); } void wxSocketInternal::PauseSocket() { - if (m_thread_waiter != NULL && !m_thread_waiter->IsPaused()) - m_thread_waiter->Pause(); + DisableWaiter(); } void wxSocketInternal::ResumeSocket() { - if (m_thread_waiter != NULL && m_thread_waiter->IsPaused()) - m_thread_waiter->Resume(); + EnableWaiter(); } void wxSocketInternal::EnableWaiter() { - if (m_thread_waiter != NULL && m_thread_waiter->IsPaused()) - m_thread_waiter->Resume(); + wxASSERT(m_thread_waiter != NULL); + if (!m_thread_waiter->IsAlive() || !m_thread_waiter->IsPaused()) + return; + + m_thread_waiter->Resume(); } void wxSocketInternal::DisableWaiter() { - if (m_thread_waiter != NULL && !m_thread_waiter->IsPaused()) - m_thread_waiter->Pause(); + wxASSERT(m_thread_waiter != NULL); + if (!m_thread_waiter->IsAlive() || m_thread_waiter->IsPaused()) + return; + + m_thread_waiter->Pause(); } // ---------------------------------------------------------------------- @@ -464,10 +463,10 @@ void wxSocketInternal::QueueRequest(SockRequest *request, bool async) m_request_locker.Lock(); request->done = FALSE; m_requests.Append((wxObject *)request); + m_socket_cond.Signal(); m_request_locker.Unlock(); // Wake up - m_socket_cond.Signal(); if (request->wait) { if (wxThread::IsMain()) diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 67113941b3..47004a9dde 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -554,11 +554,14 @@ void wxSocketBase::SetNotify(wxRequestNotify flags) void wxSocketBase::Notify(bool notify) { + m_notify_state = notify; + if (m_fd == INVALID_SOCKET) + return; + if (notify) m_internal->EnableWaiter(); else m_internal->DisableWaiter(); - m_notify_state = notify; } void wxSocketBase::OnRequest(wxRequestEvent req_evt) @@ -586,14 +589,14 @@ wxSocketEvent::wxSocketEvent(int id) SetEventType(type); } -wxObject *wxSocketEvent::Clone() const +void wxSocketEvent::CopyObject(wxObject& obj_d) const { - wxSocketEvent *event = (wxSocketEvent *)wxEvent::Clone(); + wxSocketEvent *event = (wxSocketEvent *)&obj_d; + + wxEvent::CopyObject(obj_d); event->m_skevt = m_skevt; event->m_socket = m_socket; - - return event; } void wxSocketBase::OldOnNotify(wxRequestEvent evt) @@ -746,8 +749,12 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock) { int fd2; - if ((fd2 = accept(m_fd, 0, 0)) < 0) + m_internal->AcquireFD(); + if ((fd2 = accept(m_fd, 0, 0)) < 0) { + m_internal->ReleaseFD(); return FALSE; + } + m_internal->ReleaseFD(); struct linger linger; linger.l_onoff = 0; diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 2ca841caa5..225124f277 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -914,11 +914,6 @@ int wxApp::MainLoop() DoMessage(); - - // If they are pending events, we must process them. -#if wxUSE_THREADS - ProcessPendingEvents(); -#endif } return s_currentMsg.wParam; @@ -1024,6 +1019,10 @@ void wxApp::OnIdle(wxIdleEvent& event) event.RequestMore(TRUE); } + // If they are pending events, we must process them. +#if wxUSE_THREADS + ProcessPendingEvents(); +#endif s_inOnIdle = FALSE; } @@ -1179,6 +1178,10 @@ bool wxYield() if ( !wxTheApp->DoMessage() ) break; } + // If they are pending events, we must process them. +#if wxUSE_THREADS + ProcessPendingEvents(); +#endif return TRUE; }