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 wxMemoryInputStream(wxInputStream&) ctor (Stas Sergeev)
- Implemented wxMemoryInputStream::CanRead()
- Added wxEXEC_BLOCK flag (Hank Schultz)
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
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
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

View File

@ -320,7 +320,15 @@ enum
// by default synchronous execution disables all program windows to avoid
// that the user interacts with the program while the child process is
// 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.

View File

@ -38,6 +38,7 @@
#include "wx/unix/private.h"
#include <pwd.h>
#include <sys/wait.h> // waitpid()
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
@ -1237,56 +1238,94 @@ int wxGUIAppTraits::WaitForChild(wxExecuteData& execData)
}
if ( !(flags & wxEXEC_NOEVENTS) )
{
#if defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
endProcData->tag = wxAddProcessCallbackForPid(endProcData, execData.pid);
#else
endProcData->tag = wxAddProcessCallback
(
endProcData,
execData.pipeEndProcDetect.Detach(wxPipe::Read)
);
endProcData->tag = wxAddProcessCallback
(
endProcData,
execData.pipeEndProcDetect.Detach(wxPipe::Read)
);
execData.pipeEndProcDetect.Close();
execData.pipeEndProcDetect.Close();
#endif // defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))
}
if ( flags & wxEXEC_SYNC )
{
wxBusyCursor bc;
wxWindowDisabler *wd = flags & wxEXEC_NODISABLE ? NULL
: new wxWindowDisabler;
int exitcode = 0;
// endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
// process terminates
while ( endProcData->pid != 0 )
wxWindowDisabler *wd = flags & (wxEXEC_NODISABLE | wxEXEC_NOEVENTS)
? NULL
: new wxWindowDisabler;
if ( flags & wxEXEC_NOEVENTS )
{
bool idle = true;
// 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
// process terminates
while ( endProcData->pid != 0 )
{
bool idle = true;
#if HAS_PIPE_INPUT_STREAM
if ( execData.bufOut )
{
execData.bufOut->Update();
idle = false;
}
if ( execData.bufOut )
{
execData.bufOut->Update();
idle = false;
}
if ( execData.bufErr )
{
execData.bufErr->Update();
idle = false;
}
if ( execData.bufErr )
{
execData.bufErr->Update();
idle = false;
}
#endif // HAS_PIPE_INPUT_STREAM
// don't consume 100% of the CPU while we're sitting in this
// loop
if ( idle )
wxMilliSleep(1);
// don't consume 100% of the CPU while we're sitting in this
// loop
if ( idle )
wxMilliSleep(1);
// give GTK+ a chance to call GTK_EndProcessDetector here and
// also repaint the GUI
wxYield();
// give GTK+ a chance to call GTK_EndProcessDetector here and
// also repaint the GUI
wxYield();
}
exitcode = endProcData->exitcode;
}
int exitcode = endProcData->exitcode;
delete wd;
delete endProcData;