From e1e57f73b329fe112705f3be2d02ccaedcf51643 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 3 Nov 2002 20:58:52 +0000 Subject: [PATCH] added wxPoll() implementation (based on patch 626861) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17686 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/app.cpp | 134 +++++++++++++++++++++++++++++++++++------------ src/gtk1/app.cpp | 134 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 200 insertions(+), 68 deletions(-) diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 8b84c4ae02..08a831fb19 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -46,25 +46,30 @@ #include -// TODO: use configure test to detect which of select()/poll() is available! -#if defined(__DARWIN__) - #warning "FIXME: select must be used instead of poll (GD)" -#elif defined(__VMS) - #include -#else - // bug in the OpenBSD headers: at least in 3.1 there is no extern "C" in - // neither poll.h nor sys/poll.h which results in link errors later - #ifdef __OPENBSD__ - extern "C" - { - #endif +#ifdef HAVE_POLL + #if defined(__VMS) + #include + #else + // bug in the OpenBSD headers: at least in 3.1 there is no extern "C" + // in neither poll.h nor sys/poll.h which results in link errors later + #ifdef __OPENBSD__ + extern "C" + { + #endif - #include + #include - #ifdef __OPENBSD__ - }; - #endif -#endif // platform + #ifdef __OPENBSD__ + }; + #endif + #endif // platform +#else // !HAVE_POLL + // we implement poll() ourselves using select() which is supposed exist in + // all modern Unices + #include + #include + #include +#endif // HAVE_POLL/!HAVE_POLL #include "wx/gtk/win_gtk.h" @@ -265,22 +270,82 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) ) #if wxUSE_THREADS +#ifdef HAVE_POLL + #define wxPoll poll + #define wxPollFd pollfd +#else // !HAVE_POLL + +typedef GPollFD wxPollFd; + +int wxPoll(wxPollFd *ufds, unsigned int nfds, int timeout) +{ + // convert timeout from ms to struct timeval (s/us) + timeval tv_timeout; + tv_timeout.tv_sec = timeout/1000; + tv_timeout.tv_usec = (timeout%1000)*1000; + + // remember the highest fd used here + int fdMax = -1; + + // and fill the sets for select() + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + + unsigned int i; + for ( i = 0; i < nfds; i++ ) + { + wxASSERT_MSG( ufds[i].fd < FD_SETSIZE, _T("fd out of range") ); + + if ( ufds[i].events & G_IO_IN ) + FD_SET(ufds[i].fd, &readfds); + + if ( ufds[i].events & G_IO_PRI ) + FD_SET(ufds[i].fd, &exceptfds); + + if ( ufds[i].events & G_IO_OUT ) + FD_SET(ufds[i].fd, &writefds); + + if ( ufds[i].fd > fdMax ) + fdMax = ufds[i].fd; + } + + fdMax++; + int res = select(fdMax, &readfds, &writefds, &exceptfds, &tv_timeout); + + // translate the results back + for ( i = 0; i < nfds; i++ ) + { + ufds[i].revents = 0; + + if ( FD_ISSET(ufds[i].fd, &readfds ) ) + ufds[i].revents |= G_IO_IN; + + if ( FD_ISSET(ufds[i].fd, &exceptfds ) ) + ufds[i].revents |= G_IO_PRI; + + if ( FD_ISSET(ufds[i].fd, &writefds ) ) + ufds[i].revents |= G_IO_OUT; + } + + return res; +} + +#endif // HAVE_POLL/!HAVE_POLL + static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout ) { - gint res; gdk_threads_enter(); wxMutexGuiLeave(); g_mainThreadLocked = TRUE; -#ifdef __DARWIN__ - // FIXME: poll is not available under Darwin/Mac OS X and this needs - // to be implemented using select instead (GD) - // what about other BSD derived systems? - res = -1; -#else - res = poll( (struct pollfd*) ufds, nfds, timeout ); -#endif + // we rely on the fact that glib GPollFD struct is really just pollfd but + // I wonder how wise is this in the long term (VZ) + gint res = wxPoll( (wxPollFd *) ufds, nfds, timeout ); wxMutexGuiEnter(); g_mainThreadLocked = FALSE; @@ -487,7 +552,7 @@ bool wxApp::ProcessIdle() node = node->GetNext(); } - + wxIdleEvent event; event.SetEventObject( this ); ProcessEvent( event ); @@ -498,7 +563,7 @@ bool wxApp::ProcessIdle() void wxApp::OnIdle( wxIdleEvent &event ) { static bool s_inOnIdle = FALSE; - + // Avoid recursion (via ProcessEvent default case) if (s_inOnIdle) return; @@ -626,10 +691,6 @@ bool wxApp::Initialize() { wxClassInfo::InitializeClasses(); -#if wxUSE_INTL - wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); -#endif - // GL: I'm annoyed ... I don't know where to put this and I don't want to // create a module for that as it's part of the core. #if wxUSE_THREADS @@ -648,7 +709,12 @@ bool wxApp::Initialize() #endif wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; + if (!wxModule::InitializeModules()) + return FALSE; + +#if wxUSE_INTL + wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); +#endif return TRUE; } @@ -757,7 +823,7 @@ int wxEntryInitGui() retValue = -1; wxGetRootWindow(); - + return retValue; } diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 8b84c4ae02..08a831fb19 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -46,25 +46,30 @@ #include -// TODO: use configure test to detect which of select()/poll() is available! -#if defined(__DARWIN__) - #warning "FIXME: select must be used instead of poll (GD)" -#elif defined(__VMS) - #include -#else - // bug in the OpenBSD headers: at least in 3.1 there is no extern "C" in - // neither poll.h nor sys/poll.h which results in link errors later - #ifdef __OPENBSD__ - extern "C" - { - #endif +#ifdef HAVE_POLL + #if defined(__VMS) + #include + #else + // bug in the OpenBSD headers: at least in 3.1 there is no extern "C" + // in neither poll.h nor sys/poll.h which results in link errors later + #ifdef __OPENBSD__ + extern "C" + { + #endif - #include + #include - #ifdef __OPENBSD__ - }; - #endif -#endif // platform + #ifdef __OPENBSD__ + }; + #endif + #endif // platform +#else // !HAVE_POLL + // we implement poll() ourselves using select() which is supposed exist in + // all modern Unices + #include + #include + #include +#endif // HAVE_POLL/!HAVE_POLL #include "wx/gtk/win_gtk.h" @@ -265,22 +270,82 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) ) #if wxUSE_THREADS +#ifdef HAVE_POLL + #define wxPoll poll + #define wxPollFd pollfd +#else // !HAVE_POLL + +typedef GPollFD wxPollFd; + +int wxPoll(wxPollFd *ufds, unsigned int nfds, int timeout) +{ + // convert timeout from ms to struct timeval (s/us) + timeval tv_timeout; + tv_timeout.tv_sec = timeout/1000; + tv_timeout.tv_usec = (timeout%1000)*1000; + + // remember the highest fd used here + int fdMax = -1; + + // and fill the sets for select() + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + + unsigned int i; + for ( i = 0; i < nfds; i++ ) + { + wxASSERT_MSG( ufds[i].fd < FD_SETSIZE, _T("fd out of range") ); + + if ( ufds[i].events & G_IO_IN ) + FD_SET(ufds[i].fd, &readfds); + + if ( ufds[i].events & G_IO_PRI ) + FD_SET(ufds[i].fd, &exceptfds); + + if ( ufds[i].events & G_IO_OUT ) + FD_SET(ufds[i].fd, &writefds); + + if ( ufds[i].fd > fdMax ) + fdMax = ufds[i].fd; + } + + fdMax++; + int res = select(fdMax, &readfds, &writefds, &exceptfds, &tv_timeout); + + // translate the results back + for ( i = 0; i < nfds; i++ ) + { + ufds[i].revents = 0; + + if ( FD_ISSET(ufds[i].fd, &readfds ) ) + ufds[i].revents |= G_IO_IN; + + if ( FD_ISSET(ufds[i].fd, &exceptfds ) ) + ufds[i].revents |= G_IO_PRI; + + if ( FD_ISSET(ufds[i].fd, &writefds ) ) + ufds[i].revents |= G_IO_OUT; + } + + return res; +} + +#endif // HAVE_POLL/!HAVE_POLL + static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout ) { - gint res; gdk_threads_enter(); wxMutexGuiLeave(); g_mainThreadLocked = TRUE; -#ifdef __DARWIN__ - // FIXME: poll is not available under Darwin/Mac OS X and this needs - // to be implemented using select instead (GD) - // what about other BSD derived systems? - res = -1; -#else - res = poll( (struct pollfd*) ufds, nfds, timeout ); -#endif + // we rely on the fact that glib GPollFD struct is really just pollfd but + // I wonder how wise is this in the long term (VZ) + gint res = wxPoll( (wxPollFd *) ufds, nfds, timeout ); wxMutexGuiEnter(); g_mainThreadLocked = FALSE; @@ -487,7 +552,7 @@ bool wxApp::ProcessIdle() node = node->GetNext(); } - + wxIdleEvent event; event.SetEventObject( this ); ProcessEvent( event ); @@ -498,7 +563,7 @@ bool wxApp::ProcessIdle() void wxApp::OnIdle( wxIdleEvent &event ) { static bool s_inOnIdle = FALSE; - + // Avoid recursion (via ProcessEvent default case) if (s_inOnIdle) return; @@ -626,10 +691,6 @@ bool wxApp::Initialize() { wxClassInfo::InitializeClasses(); -#if wxUSE_INTL - wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); -#endif - // GL: I'm annoyed ... I don't know where to put this and I don't want to // create a module for that as it's part of the core. #if wxUSE_THREADS @@ -648,7 +709,12 @@ bool wxApp::Initialize() #endif wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; + if (!wxModule::InitializeModules()) + return FALSE; + +#if wxUSE_INTL + wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); +#endif return TRUE; } @@ -757,7 +823,7 @@ int wxEntryInitGui() retValue = -1; wxGetRootWindow(); - + return retValue; }