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:
@@ -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):
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
|
@@ -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,56 +1238,94 @@ 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
|
||||||
endProcData->tag = wxAddProcessCallback
|
endProcData->tag = wxAddProcessCallback
|
||||||
(
|
(
|
||||||
endProcData,
|
endProcData,
|
||||||
execData.pipeEndProcDetect.Detach(wxPipe::Read)
|
execData.pipeEndProcDetect.Detach(wxPipe::Read)
|
||||||
);
|
);
|
||||||
|
|
||||||
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;
|
||||||
: new wxWindowDisabler;
|
|
||||||
|
|
||||||
// endProcData->pid will be set to 0 from GTK_EndProcessDetector when the
|
wxWindowDisabler *wd = flags & (wxEXEC_NODISABLE | wxEXEC_NOEVENTS)
|
||||||
// process terminates
|
? NULL
|
||||||
while ( endProcData->pid != 0 )
|
: 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 HAS_PIPE_INPUT_STREAM
|
||||||
if ( execData.bufOut )
|
if ( execData.bufOut )
|
||||||
{
|
{
|
||||||
execData.bufOut->Update();
|
execData.bufOut->Update();
|
||||||
idle = false;
|
idle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( execData.bufErr )
|
if ( execData.bufErr )
|
||||||
{
|
{
|
||||||
execData.bufErr->Update();
|
execData.bufErr->Update();
|
||||||
idle = false;
|
idle = false;
|
||||||
}
|
}
|
||||||
#endif // HAS_PIPE_INPUT_STREAM
|
#endif // HAS_PIPE_INPUT_STREAM
|
||||||
|
|
||||||
// don't consume 100% of the CPU while we're sitting in this
|
// don't consume 100% of the CPU while we're sitting in this
|
||||||
// loop
|
// loop
|
||||||
if ( idle )
|
if ( idle )
|
||||||
wxMilliSleep(1);
|
wxMilliSleep(1);
|
||||||
|
|
||||||
// give GTK+ a chance to call GTK_EndProcessDetector here and
|
// give GTK+ a chance to call GTK_EndProcessDetector here and
|
||||||
// also repaint the GUI
|
// also repaint the GUI
|
||||||
wxYield();
|
wxYield();
|
||||||
|
}
|
||||||
|
|
||||||
|
exitcode = endProcData->exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitcode = endProcData->exitcode;
|
|
||||||
|
|
||||||
delete wd;
|
delete wd;
|
||||||
delete endProcData;
|
delete endProcData;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user