| The Gaudi Framework v27r1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
GaudiTest.GaudiFilterExecutable Class Reference
Inheritance diagram for GaudiTest.GaudiFilterExecutable:
[legend]
Collaboration diagram for GaudiTest.GaudiFilterExecutable:
[legend]

## Public Member Functions
def | __init__

## Public Attributes
| stack_trace_file

## Private Member Functions
def | __UseSeparateProcessGroupForChild (self)
def | _HandleChild (self)
| Needs to replace the ones from RedirectedExecutable and TimeoutExecutable. More...
def | __Monitor (self)

## Private Attributes
| __input
| __timeout
| __monitor_pid
| __monitor_thread
| This is the interesting part: dump the stack trace to a file. More...

## Detailed Description

Definition at line 911 of file GaudiTest.py.

## Constructor & Destructor Documentation

def GaudiTest.GaudiFilterExecutable.__init__ | ( |  | self,
|  |  | input,
|  |  | timeout = `-1`
| ) |  |

    Create a new 'Filter'.

    'input' -- The string containing the input to provide to the
    child process.

    'timeout' -- As for 'TimeoutExecutable.__init__'.

Definition at line 912 of file GaudiTest.py.

912 def __init__(self, input, timeout = -1):
913 """Create a new 'Filter'.
914
915 'input' -- The string containing the input to provide to the
916 child process.
917
918 'timeout' -- As for 'TimeoutExecutable.__init__'."""
919
920 super(GaudiFilterExecutable, self).__init__(input, timeout)
921 self.__input = input
922 self.__timeout = timeout
923 self.stack_trace_file = None
924 # Temporary file to pass the stack trace from one process to the other
925 # The file must be closed and reopened when needed to avoid conflicts
926 # between the processes
927 tmpf = tempfile.mkstemp()
928 os.close(tmpf[0])
929 self.stack_trace_file = tmpf[1] # remember only the name
930
GaudiTest.GaudiFilterExecutable.__input
__input
Definition: GaudiTest.py:921
GaudiTest.GaudiFilterExecutable.__timeout
__timeout
Definition: GaudiTest.py:922
GaudiTest.GaudiFilterExecutable.__init__
def __init__
Definition: GaudiTest.py:912
GaudiTest.GaudiFilterExecutable.stack_trace_file
stack_trace_file
Definition: GaudiTest.py:923

## Member Function Documentation

def GaudiTest.GaudiFilterExecutable.__Monitor | ( |  | self | ) |
| private

    Code copied from FilterExecutable.
    Kill the child if the timeout expires.

    This function is run in the monitoring thread.

Definition at line 1050 of file GaudiTest.py.

1050 def __Monitor(self):
1051 """Code copied from FilterExecutable.
1052 Kill the child if the timeout expires.
1053
1054 This function is run in the monitoring thread."""
1055
1056 # The timeout may be expressed as a floating-point value
1057 # on UNIX, but it must be an integer number of
1058 # milliseconds when passed to WaitForSingleObject.
1059 timeout = int(self.__timeout * 1000)
1060 # Wait for the child process to terminate or for the
1061 # timer to expire.
1062 result = win32event.WaitForSingleObject(self._GetChildPID(),
1063 timeout)
1064 # If the timeout occurred, kill the child process.
1065 if result == win32con.WAIT_TIMEOUT:
1066 self.Kill()
1067
GaudiTest.GaudiFilterExecutable.__timeout
__timeout
Definition: GaudiTest.py:922
GaudiTest.GaudiFilterExecutable.__Monitor
def __Monitor(self)
Definition: GaudiTest.py:1050

def GaudiTest.GaudiFilterExecutable.__UseSeparateProcessGroupForChild | ( |  | self | ) |
| private

    Copied from TimeoutExecutable to allow the re-implementation of
       _HandleChild.

Definition at line 931 of file GaudiTest.py.

931 def __UseSeparateProcessGroupForChild(self):
932 """Copied from TimeoutExecutable to allow the re-implementation of
933 _HandleChild.
934 """
935 if sys.platform == "win32":
936 # In Windows 2000 (or later), we should use "jobs" by
937 # analogy with UNIX process groups. However, that
938 # functionality is not (yet) provided by the Python Win32
939 # extensions.
940 return 0
941
942 return self.__timeout >= 0 or self.__timeout == -2
GaudiTest.GaudiFilterExecutable.__timeout
__timeout
Definition: GaudiTest.py:922
GaudiTest.GaudiFilterExecutable.__UseSeparateProcessGroupForChild
def __UseSeparateProcessGroupForChild(self)
Definition: GaudiTest.py:931

def GaudiTest.GaudiFilterExecutable._HandleChild | ( |  | self | ) |
| private

Needs to replace the ones from RedirectedExecutable and TimeoutExecutable.

    Code copied from both FilterExecutable and TimeoutExecutable.

Definition at line 945 of file GaudiTest.py.

945 def _HandleChild(self):
946 """Code copied from both FilterExecutable and TimeoutExecutable.
947 """
948 # Close the pipe ends that we do not need.
949 if self._stdin_pipe:
950 self._ClosePipeEnd(self._stdin_pipe[0])
951 if self._stdout_pipe:
952 self._ClosePipeEnd(self._stdout_pipe[1])
953 if self._stderr_pipe:
954 self._ClosePipeEnd(self._stderr_pipe[1])
955
956 # The pipes created by 'RedirectedExecutable' must be closed
957 # before the monitor process (created by 'TimeoutExecutable')
958 # is created. Otherwise, if the child process dies, 'select'
959 # in the parent will not return if the monitor process may
960 # still have one of the file descriptors open.
961
962 super(qm.executable.TimeoutExecutable, self)._HandleChild()
963
964 if self.__UseSeparateProcessGroupForChild():
965 # Put the child into its own process group. This step is
966 # performed in both the parent and the child; therefore both
967 # processes can safely assume that the creation of the process
968 # group has taken place.
969 child_pid = self._GetChildPID()
970 try:
971 os.setpgid(child_pid, child_pid)
972 except:
973 # The call to setpgid may fail if the child has exited,
974 # or has already called 'exec'. In that case, we are
975 # guaranteed that the child has already put itself in the
976 # desired process group.
977 pass
978 # Create the monitoring process.
979 #
980 # If the monitoring process is in parent's process group and
981 # kills the child after waitpid has returned in the parent, we
982 # may end up trying to kill a process group other than the one
983 # that we intend to kill. Therefore, we put the monitoring
984 # process in the same process group as the child; that ensures
985 # that the process group will persist until the monitoring
986 # process kills it.
987 self.__monitor_pid = os.fork()
988 if self.__monitor_pid != 0:
989 # Make sure that the monitoring process is placed into the
990 # child's process group before the parent process calls
991 # 'waitpid'. In this way, we are guaranteed that the process
992 # group as the child
993 os.setpgid(self.__monitor_pid, child_pid)
994 else:
995 # Put the monitoring process into the child's process
996 # group. We know the process group still exists at
997 # this point because either (a) we are in the process
998 # group, or (b) the parent has not yet called waitpid.
999 os.setpgid(0, child_pid)
1000
1001 # Close all open file descriptors. They are not needed
1002 # in the monitor process. Furthermore, when the parent
1003 # closes the write end of the stdin pipe to the child,
1004 # we do not want the pipe to remain open; leaving the
1005 # pipe open in the monitor process might cause the child
1006 # to block waiting for additional input.
1007 try:
1008 max_fds = os.sysconf("SC_OPEN_MAX")
1009 except:
1010 max_fds = 256
1011 for fd in xrange(max_fds):
1012 try:
1013 os.close(fd)
1014 except:
1015 pass
1016 try:
1017 if self.__timeout >= 0:
1018 # Give the child time to run.
1019 time.sleep (self.__timeout)
1020 #######################################################
1021 ### This is the interesting part: dump the stack trace to a file
1022 if sys.platform == "linux2": # we should be have /proc and gdb
1023 cmd = ["gdb",
1024 os.path.join("/proc", str(child_pid), "exe"),
1025 str(child_pid),
1026 "-batch", "-n", "-x",
1027 "'%s'" % os.path.join(os.path.dirname(__file__), "stack-trace.gdb")]
1028 # FIXME: I wanted to use subprocess.Popen, but it doesn't want to work
1029 # in this context.
1030 o = os.popen(" ".join(cmd)).read()
1031 open(self.stack_trace_file,"w").write(o)
1032 #######################################################
1033
1034 # Kill all processes in the child process group.
1035 os.kill(0, signal.SIGKILL)
1036 else:
1037 # This call to select will never terminate.
1038 select.select ([], [], [])
1039 finally:
1040 # Exit. This code is in a finally clause so that
1041 # we are guaranteed to get here no matter what.
1042 os._exit(0)
1043 elif self.__timeout >= 0 and sys.platform == "win32":
1044 # Create a monitoring thread.
1045 self.__monitor_thread = Thread(target = self.__Monitor)
1046 self.__monitor_thread.start()
1047
GaudiTest.GaudiFilterExecutable._HandleChild
def _HandleChild(self)
Needs to replace the ones from RedirectedExecutable and TimeoutExecutable.
Definition: GaudiTest.py:945
GaudiTest.GaudiFilterExecutable.__timeout
__timeout
Definition: GaudiTest.py:922
GaudiTest.GaudiFilterExecutable.__monitor_thread
__monitor_thread
This is the interesting part: dump the stack trace to a file.
Definition: GaudiTest.py:1045
GaudiTest.GaudiFilterExecutable.__Monitor
def __Monitor(self)
Definition: GaudiTest.py:1050
GaudiTest.GaudiFilterExecutable.__UseSeparateProcessGroupForChild
def __UseSeparateProcessGroupForChild(self)
Definition: GaudiTest.py:931
GaudiTest.GaudiFilterExecutable.__monitor_pid
__monitor_pid
Definition: GaudiTest.py:987
GaudiTest.GaudiFilterExecutable.stack_trace_file
stack_trace_file
Definition: GaudiTest.py:923

## Member Data Documentation

GaudiTest.GaudiFilterExecutable.__input
| private

Definition at line 921 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__monitor_pid
| private

Definition at line 987 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__monitor_thread
| private

This is the interesting part: dump the stack trace to a file.

Definition at line 1045 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__timeout
| private

Definition at line 922 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.stack_trace_file

Definition at line 923 of file GaudiTest.py.

The documentation for this class was generated from the following file:

- GaudiPolicy/qmtest_classes/GaudiTest.py