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
This commit is contained in:
Vadim Zeitlin
2008-03-15 16:46:38 +00:00
parent a568316bc5
commit 9243700fb2
6 changed files with 37 additions and 51 deletions

View File

@@ -193,6 +193,7 @@ Major new features in this release
All: All:
- Added (experimental) IPv6 support to wxSocket (Arcen) - 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 - Added wxXLocale class and xlocale-like functions using it
- Allow loading message catalogs from wxFileSystem (Axel Gembe) - Allow loading message catalogs from wxFileSystem (Axel Gembe)
- Added wxMessageQueue class for inter-thread communications - Added wxMessageQueue class for inter-thread communications

View File

@@ -30,14 +30,14 @@ public:
// wxBase // wxBase
// //
// if it returns false, we should return from wxExecute() with an error // 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 // test if the given descriptor is the end of the pipe create by the
// function above // 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 // 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 // wait for the process termination, return whatever wxExecute() must
// return // return

View File

@@ -22,9 +22,6 @@ public:
#if wxUSE_CONSOLE_EVENTLOOP #if wxUSE_CONSOLE_EVENTLOOP
virtual wxEventLoopBase *CreateEventLoop(); virtual wxEventLoopBase *CreateEventLoop();
#endif // wxUSE_CONSOLE_EVENTLOOP #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); virtual int WaitForChild(wxExecuteData& execData);
#if wxUSE_TIMER #if wxUSE_TIMER
virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer); virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer);
@@ -37,9 +34,6 @@ class WXDLLEXPORT wxGUIAppTraits : public wxGUIAppTraitsBase
{ {
public: public:
virtual wxEventLoopBase *CreateEventLoop(); 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); virtual int WaitForChild(wxExecuteData& execData);
#if wxUSE_TIMER #if wxUSE_TIMER
virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer); virtual wxTimerImpl *CreateTimerImpl(wxTimer *timer);

View File

@@ -15,7 +15,7 @@
class WXDLLIMPEXP_FWD_BASE wxProcess; class WXDLLIMPEXP_FWD_BASE wxProcess;
class wxStreamTempInputBuffer; class wxStreamTempInputBuffer;
#if defined(__WXDFB__) || defined(__WXX11__) #if defined(__UNIX__)
#define wxHAS_GENERIC_PROCESS_CALLBACK 1 #define wxHAS_GENERIC_PROCESS_CALLBACK 1
#endif #endif

View File

@@ -45,42 +45,32 @@
// wxConsoleAppTraits implementation // 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 int
wxConsoleAppTraits::WaitForChild(wxExecuteData& execData) wxConsoleAppTraits::WaitForChild(wxExecuteData& execData)
{ {
wxASSERT_MSG( execData.flags & wxEXEC_SYNC,
wxT("async execution not supported yet") );
int exitcode = 0; int exitcode = 0;
if ( execData.flags & wxEXEC_SYNC )
{
if ( waitpid(execData.pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) ) if ( waitpid(execData.pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) )
{ {
wxLogSysError(_("Waiting for subprocess termination failed")); wxLogSysError(_("Waiting for subprocess termination failed"));
} }
}
else // asynchronous execution
{
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; return exitcode;
} }

View File

@@ -1222,8 +1222,6 @@ bool wxHandleFatalExceptions(bool doit)
#endif // wxUSE_BASE #endif // wxUSE_BASE
#if wxUSE_GUI
#ifdef __DARWIN__ #ifdef __DARWIN__
#include <sys/errno.h> #include <sys/errno.h>
#endif #endif
@@ -1246,17 +1244,17 @@ bool wxHandleFatalExceptions(bool doit)
// need wxExecute-related helpers for them // need wxExecute-related helpers for them
#if !USE_OLD_DARWIN_END_PROCESS_DETECT #if !USE_OLD_DARWIN_END_PROCESS_DETECT
bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& execData) bool wxAppTraits::CreateEndProcessPipe(wxExecuteData& execData)
{ {
return execData.pipeEndProcDetect.Create(); return execData.pipeEndProcDetect.Create();
} }
bool wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd) bool wxAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& execData, int fd)
{ {
return fd == (execData.pipeEndProcDetect)[wxPipe::Write]; return fd == (execData.pipeEndProcDetect)[wxPipe::Write];
} }
void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData) void wxAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData)
{ {
execData.pipeEndProcDetect.Detach(wxPipe::Write); execData.pipeEndProcDetect.Detach(wxPipe::Write);
execData.pipeEndProcDetect.Close(); execData.pipeEndProcDetect.Close();
@@ -1264,26 +1262,28 @@ void wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& execData)
#else // !Darwin #else // !Darwin
bool wxGUIAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData)) bool wxAppTraits::CreateEndProcessPipe(wxExecuteData& WXUNUSED(execData))
{ {
return true; return true;
} }
bool bool
wxGUIAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData), wxAppTraits::IsWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData),
int WXUNUSED(fd)) int WXUNUSED(fd))
{ {
return false; return false;
} }
void void
wxGUIAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData)) wxAppTraits::DetachWriteFDOfEndProcessPipe(wxExecuteData& WXUNUSED(execData))
{ {
// nothing to do here, we don't use the pipe // nothing to do here, we don't use the pipe
} }
#endif // !Darwin/Darwin #endif // !Darwin/Darwin
#if wxUSE_GUI
int wxGUIAppTraits::WaitForChild(wxExecuteData& execData) int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
{ {
wxEndProcessData *endProcData = new wxEndProcessData; wxEndProcessData *endProcData = new wxEndProcessData;
@@ -1440,6 +1440,10 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
} }
} }
#endif //wxUSE_GUI
#if wxUSE_BASE
#ifdef wxHAS_GENERIC_PROCESS_CALLBACK #ifdef wxHAS_GENERIC_PROCESS_CALLBACK
struct wxEndProcessFDIOHandler : public wxFDIOHandler struct wxEndProcessFDIOHandler : public wxFDIOHandler
{ {
@@ -1512,9 +1516,6 @@ int wxAddProcessCallback(wxEndProcessData *proc_data, int fd)
} }
#endif // wxHAS_GENERIC_PROCESS_CALLBACK #endif // wxHAS_GENERIC_PROCESS_CALLBACK
#endif // wxUSE_GUI
#if wxUSE_BASE
void wxHandleProcessTermination(wxEndProcessData *proc_data) void wxHandleProcessTermination(wxEndProcessData *proc_data)
{ {
// notify user about termination if required // notify user about termination if required