| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

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

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

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
def | _HandleChild
| Needs to replace the ones from RedirectedExecutable and TimeoutExecutable.
def | __Monitor

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

## Detailed Description

Definition at line 889 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 890 of file GaudiTest.py.

890
891 def __init__(self, input, timeout = -1):
892 """Create a new 'Filter'.
893
894 'input' -- The string containing the input to provide to the
895 child process.
896
897 'timeout' -- As for 'TimeoutExecutable.__init__'."""
898
899 super(GaudiFilterExecutable, self).__init__(input, timeout)
900 self.__input = input
901 self.__timeout = timeout
902 self.stack_trace_file = None
903 # Temporary file to pass the stack trace from one process to the other
904 # The file must be closed and reopened when needed to avoid conflicts
905 # between the processes
906 tmpf = tempfile.mkstemp()
907 os.close(tmpf[0])
908 self.stack_trace_file = tmpf[1] # remember only the name

## 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 1028 of file GaudiTest.py.

1028
1029 def __Monitor(self):
1030 """Code copied from FilterExecutable.
1031 Kill the child if the timeout expires.
1032
1033 This function is run in the monitoring thread."""
1034
1035 # The timeout may be expressed as a floating-point value
1036 # on UNIX, but it must be an integer number of
1037 # milliseconds when passed to WaitForSingleObject.
1038 timeout = int(self.__timeout * 1000)
1039 # Wait for the child process to terminate or for the
1040 # timer to expire.
1041 result = win32event.WaitForSingleObject(self._GetChildPID(),
1042 timeout)
1043 # If the timeout occurred, kill the child process.
1044 if result == win32con.WAIT_TIMEOUT:
1045 self.Kill()

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

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

Definition at line 909 of file GaudiTest.py.

909
910 def __UseSeparateProcessGroupForChild(self):
911 """Copied from TimeoutExecutable to allow the re-implementation of
912 _HandleChild.
913 """
914 if sys.platform == "win32":
915 # In Windows 2000 (or later), we should use "jobs" by
916 # analogy with UNIX process groups. However, that
917 # functionality is not (yet) provided by the Python Win32
918 # extensions.
919 return 0
920
return self.__timeout >= 0 or self.__timeout == -2

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 923 of file GaudiTest.py.

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

## Member Data Documentation

GaudiTest.GaudiFilterExecutable.__input
| private

Definition at line 899 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__monitor_pid
| private

Definition at line 965 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__monitor_thread
| private

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

Definition at line 1023 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.__timeout
| private

Definition at line 900 of file GaudiTest.py.

GaudiTest.GaudiFilterExecutable.stack_trace_file

Definition at line 901 of file GaudiTest.py.

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

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v25r0/GaudiPolicy/qmtest_classes/GaudiTest.py