added wxEXEC_BLOCK flag (patch 1620430)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45325 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-04-08 00:18:09 +00:00
parent f605c2584f
commit bc855d0932
4 changed files with 88 additions and 33 deletions

View File

@@ -79,6 +79,7 @@ All:
- Added wxMutex::LockTimeout() (Aleksandr Napylov) - Added wxMutex::LockTimeout() (Aleksandr Napylov)
- Added wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev) - Added wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev)
- Implemented wxMemoryInputStream::CanRead() - Implemented wxMemoryInputStream::CanRead()
- Added wxEXEC_BLOCK flag (Hank Schultz)
All (GUI): All (GUI):

View File

@@ -647,6 +647,13 @@ needed). Calling \helpref{wxKill}{wxkill} passing wxKILL\_CHILDREN will
kill this process as well as all of its children (except those which have kill this process as well as all of its children (except those which have
started their own session). started their own session).
The {\tt wxEXEC\_NOEVENTS} flag prevents processing of any events from taking
place while the child process is running. It should be only used for very
short-lived processes as otherwise the application windows risk becoming
unresponsive from the users point of view. As this flag only makes sense with
{\tt wxEXEC\_SYNC}, {\tt wxEXEC\_BLOCK} equal to the sum of both of these flags
is provided as a convenience.
Finally, you may use the third overloaded version of this function to execute Finally, you may use the third overloaded version of this function to execute
a process (always synchronously, the contents of \arg{flags} is or'd with a process (always synchronously, the contents of \arg{flags} is or'd with
\texttt{wxEXEC\_SYNC}) and capture its output in the array \arg{output}. The \texttt{wxEXEC\_SYNC}) and capture its output in the array \arg{output}. The

View File

@@ -320,7 +320,15 @@ enum
// by default synchronous execution disables all program windows to avoid // by default synchronous execution disables all program windows to avoid
// that the user interacts with the program while the child process is // that the user interacts with the program while the child process is
// running, you can use this flag to prevent this from happening // running, you can use this flag to prevent this from happening
wxEXEC_NODISABLE = 8 wxEXEC_NODISABLE = 8,
// by default, the event loop is run while waiting for synchronous execution
// to complete and this flag can be used to simply block the main process
// until the child process finishes
wxEXEC_NOEVENTS = 16,
// convenient synonym for flags given system()-like behaviour
wxEXEC_BLOCK = wxEXEC_SYNC | wxEXEC_NOEVENTS
}; };
// Execute another program. // Execute another program.

View File

@@ -38,6 +38,7 @@
#include "wx/unix/private.h" #include "wx/unix/private.h"
#include <pwd.h> #include <pwd.h>
#include <sys/wait.h> // waitpid()
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
# include <sys/select.h> # include <sys/select.h>
@@ -1237,6 +1238,8 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
} }
if ( !(flags & wxEXEC_NOEVENTS) )
{
#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__)) #if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid); endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
#else #else
@@ -1248,13 +1251,48 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
execData.pipeEndProcDetect.Close(); execData.pipeEndProcDetect.Close();
#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__)) #endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
}
if ( flags & wxEXEC_SYNC ) if ( flags & wxEXEC_SYNC )
{ {
wxBusyCursor bc; wxBusyCursor bc;
wxWindowDisabler *wd = flags & wxEXEC_NODISABLE ? NULL int exitcode = 0;
wxWindowDisabler *wd = flags & (wxEXEC_NODISABLE | wxEXEC_NOEVENTS)
? NULL
: new wxWindowDisabler; : new wxWindowDisabler;
if ( flags & wxEXEC_NOEVENTS )
{
// just block waiting for the child to exit
int status = 0;
int result = waitpid(execData.pid, &status, 0);
if ( result == -1 )
{
wxLogLastError(_T("waitpid"));
exitcode = -1;
}
else
{
wxASSERT_MSG( result == execData.pid,
_T("unexpected waitpid() return value") );
if ( WIFEXITED(status) )
{
exitcode = WEXITSTATUS(status);
}
else // abnormal termination?
{
wxASSERT_MSG( WIFSIGNALED(status),
_T("unexpected child wait status") );
exitcode = -1;
}
}
}
else // !wxEXEC_NOEVENTS
{
// endProcData->pid will be set to 0 from GTK_EndProcessDetector when the // endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
// process terminates // process terminates
while ( endProcData->pid != 0 ) while ( endProcData->pid != 0 )
@@ -1285,7 +1323,8 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
wxYield(); wxYield();
} }
int exitcode = endProcData->exitcode; exitcode = endProcData->exitcode;
}
delete wd; delete wd;
delete endProcData; delete endProcData;