From: Vadim Zeitlin Date: Sat, 15 Mar 2008 16:46:38 +0000 (+0000) Subject: add support for asynchronous execution in wxBase (patch 1906889) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9243700fb212c2508c4d4c80fb8eb968e565e44d add support for asynchronous execution in wxBase (patch 1906889) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@52550 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 75c85fa136..3020e542fa 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -193,6 +193,7 @@ Major new features in this release All: - Added (experimental) IPv6 support to wxSocket (Arcen) +- Add support for wxExecute(wxEXEC_ASYNC) in wxBase (Lukasz Michalski) - Added wxXLocale class and xlocale-like functions using it - Allow loading message catalogs from wxFileSystem (Axel Gembe) - Added wxMessageQueue class for inter-thread communications diff --git a/include/wx/unix/apptbase.h b/include/wx/unix/apptbase.h index 50f30040f8..afb6663643 100644 --- a/include/wx/unix/apptbase.h +++ b/include/wx/unix/apptbase.h @@ -30,14 +30,14 @@ public: // wxBase // // if it returns false, we should return from wxExecute() with an error - virtual bool CreateEndProcessPipe(wxExecuteData& execData) = 0; + virtual bool CreateEndProcessPipe(wxExecuteData& execData); // test if the given descriptor is the end of the pipe create by the // function above - virtual bool IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd) = 0; + virtual bool IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd); // ensure that the write end of the pipe is not closed by wxPipe dtor - virtual void DetachWriteFDOfEndProcessPipe(wxExecuteData& execData) = 0; + virtual void DetachWriteFDOfEndProcessPipe(wxExecuteData& execData); // wait for the process termination, return whatever wxExecute() must // return diff --git a/include/wx/unix/apptrait.h b/include/wx/unix/apptrait.h index fe5639731a..3c172d803b 100644 --- a/include/wx/unix/apptrait.h +++ b/include/wx/unix/apptrait.h @@ -22,9 +22,6 @@ public: #if wxUSE_CONSOLE_EVENTLOOP virtual wxEventLoopBase *CreateEventLoop(); #endif // wxUSE_CONSOLE_EVENTLOOP - virtual bool CreateEndProcessPipe(wxExecuteData& execData); - virtual bool IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd); - virtual void DetachWriteFDOfEndProcessPipe(wxExecuteData& execData); virtual int WaitForChild(wxExecuteData& execData); #if wxUSE_TIMER virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer); @@ -37,9 +34,6 @@ class WXDLLEXPORT wxGUIAppTraits : public wxGUIAppTraitsBase { public: virtual wxEventLoopBase *CreateEventLoop(); - virtual bool CreateEndProcessPipe(wxExecuteData& execData); - virtual bool IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd); - virtual void DetachWriteFDOfEndProcessPipe(wxExecuteData& execData); virtual int WaitForChild(wxExecuteData& execData); #if wxUSE_TIMER virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer); diff --git a/include/wx/unix/execute.h b/include/wx/unix/execute.h index 25376c0cdd..e8baeec132 100644 --- a/include/wx/unix/execute.h +++ b/include/wx/unix/execute.h @@ -15,7 +15,7 @@ class WXDLLIMPEXP_FWD_BASE wxProcess; class wxStreamTempInputBuffer; -#if defined(__WXDFB__) || defined(__WXX11__) +#if defined(__UNIX__) #define wxHAS_GENERIC_PROCESS_CALLBACK 1 #endif diff --git a/src/unix/baseunix.cpp b/src/unix/baseunix.cpp index 01d4281e9d..c5e3ddcee1 100644 --- a/src/unix/baseunix.cpp +++ b/src/unix/baseunix.cpp @@ -45,41 +45,31 @@ // wxConsoleAppTraits implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// wxExecute support -// ---------------------------------------------------------------------------- - -bool wxConsoleAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(data)) -{ - // nothing to do, so always ok - return true; -} - -bool -wxConsoleAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(data), - int WXUNUSED(fd)) -{ - // we don't have any pipe - return false; -} - -void -wxConsoleAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(data)) -{ - // nothing to do -} - - int wxConsoleAppTraits::WaitForChild(wxExecuteData& execData) { - wxASSERT_MSG( execData.flags & wxEXEC_SYNC, - wxT("async execution not supported yet") ); - int exitcode = 0; - if ( waitpid(execData.pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) ) + if ( execData.flags & wxEXEC_SYNC ) + { + if ( waitpid(execData.pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) ) + { + wxLogSysError(_("Waiting for subprocess termination failed")); + } + } + else // asynchronous execution { - wxLogSysError(_("Waiting for subprocess termination failed")); + wxEndProcessData *endProcData = new wxEndProcessData; + endProcData->process = execData.process; + endProcData->pid = execData.pid; + endProcData->tag = wxAddProcessCallback + ( + endProcData, + execData.pipeEndProcDetect.Detach(wxPipe::Read) + ); + + execData.pipeEndProcDetect.Close(); + exitcode = execData.pid; + } return exitcode; diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index 12d1e9eb06..2b5056af5f 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -1222,8 +1222,6 @@ bool wxHandleFatalExceptions(bool doit) #endif // wxUSE_BASE -#if wxUSE_GUI - #ifdef __DARWIN__ #include #endif @@ -1246,17 +1244,17 @@ bool wxHandleFatalExceptions(bool doit) // need wxExecute-related helpers for them #if !USE_OLD_DARWIN_END_PROCESS_DETECT -bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData) +bool wxAppTraits::CreateEndProcessPipe(wxExecuteData& execData) { return execData.pipeEndProcDetect.Create(); } -bool wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd) +bool wxAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd) { return fd == (execData.pipeEndProcDetect)[wxPipe::Write]; } -void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData) +void wxAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData) { execData.pipeEndProcDetect.Detach(wxPipe::Write); execData.pipeEndProcDetect.Close(); @@ -1264,26 +1262,28 @@ void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData) #else // !Darwin -bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData)) +bool wxAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData)) { return true; } bool -wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData), +wxAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData), int WXUNUSED(fd)) { return false; } void -wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData)) +wxAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData)) { // nothing to do here, we don't use the pipe } #endif // !Darwin/Darwin +#if wxUSE_GUI + int wxGUIAppTraits::WaitForChild(wxExecuteData& execData) { wxEndProcessData *endProcData = new wxEndProcessData; @@ -1440,6 +1440,10 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData) } } +#endif //wxUSE_GUI + +#if wxUSE_BASE + #ifdef wxHAS_GENERIC_PROCESS_CALLBACK struct wxEndProcessFDIOHandler : public wxFDIOHandler { @@ -1512,9 +1516,6 @@ int wxAddProcessCallback(wxEndProcessData *proc_data, int fd) } #endif // wxHAS_GENERIC_PROCESS_CALLBACK -#endif // wxUSE_GUI -#if wxUSE_BASE - void wxHandleProcessTermination(wxEndProcessData *proc_data) { // notify user about termination if required