| The Gaudi Framework v32r1 (f65d50dc)

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__ (self, input, timeout=-1)

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

## Constructor & Destructor Documentation

## ◆ __init__()

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

1017 def __init__(self, input, timeout=-1):
1018 """Create a new 'Filter'.
1019
1020 'input' -- The string containing the input to provide to the
1021 child process.
1022
1023 'timeout' -- As for 'TimeoutExecutable.__init__'."""
1024
1025 super(GaudiFilterExecutable, self).__init__(input, timeout)
1026 self.__input = input
1027 self.__timeout = timeout
1028 self.stack_trace_file = None
1029 # Temporary file to pass the stack trace from one process to the other
1030 # The file must be closed and reopened when needed to avoid conflicts
1031 # between the processes
1032 tmpf = tempfile.mkstemp()
1033 os.close(tmpf[0])
1034 self.stack_trace_file = tmpf[1] # remember only the name
1035

## Member Function Documentation

## ◆ __Monitor()

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

1160 def __Monitor(self):
1161 """Code copied from FilterExecutable.
1162 Kill the child if the timeout expires.
1163
1164 This function is run in the monitoring thread."""
1165
1166 # The timeout may be expressed as a floating-point value
1167 # on UNIX, but it must be an integer number of
1168 # milliseconds when passed to WaitForSingleObject.
1169 timeout = int(self.__timeout * 1000)
1170 # Wait for the child process to terminate or for the
1171 # timer to expire.
1172 result = win32event.WaitForSingleObject(self._GetChildPID(),
1173 timeout)
1174 # If the timeout occurred, kill the child process.
1175 if result == win32con.WAIT_TIMEOUT:
1176 self.Kill()
1177
1178

## ◆ __UseSeparateProcessGroupForChild()

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

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

Definition at line 1036 of file GaudiTest.py.

1036 def __UseSeparateProcessGroupForChild(self):
1037 """Copied from TimeoutExecutable to allow the re-implementation of
1038 _HandleChild.
1039 """
1040 if sys.platform == "win32":
1041 # In Windows 2000 (or later), we should use "jobs" by
1042 # analogy with UNIX process groups. However, that
1043 # functionality is not (yet) provided by the Python Win32
1044 # extensions.
1045 return 0
1046
1047 return self.__timeout >= 0 or self.__timeout == -2
1048

## ◆ _HandleChild()

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

1052 def _HandleChild(self):
1053 """Code copied from both FilterExecutable and TimeoutExecutable.
1054 """
1055 # Close the pipe ends that we do not need.
1056 if self._stdin_pipe:
1057 self._ClosePipeEnd(self._stdin_pipe[0])
1058 if self._stdout_pipe:
1059 self._ClosePipeEnd(self._stdout_pipe[1])
1060 if self._stderr_pipe:
1061 self._ClosePipeEnd(self._stderr_pipe[1])
1062
1063 # The pipes created by 'RedirectedExecutable' must be closed
1064 # before the monitor process (created by 'TimeoutExecutable')
1065 # is created. Otherwise, if the child process dies, 'select'
1066 # in the parent will not return if the monitor process may
1067 # still have one of the file descriptors open.
1068
1069 super(qm.executable.TimeoutExecutable, self)._HandleChild()
1070
1071 if self.__UseSeparateProcessGroupForChild():
1072 # Put the child into its own process group. This step is
1073 # performed in both the parent and the child; therefore both
1074 # processes can safely assume that the creation of the process
1075 # group has taken place.
1076 child_pid = self._GetChildPID()
1077 try:
1078 os.setpgid(child_pid, child_pid)
1079 except:
1080 # The call to setpgid may fail if the child has exited,
1081 # or has already called 'exec'. In that case, we are
1082 # guaranteed that the child has already put itself in the
1083 # desired process group.
1084 pass
1085 # Create the monitoring process.
1086 #
1087 # If the monitoring process is in parent's process group and
1088 # kills the child after waitpid has returned in the parent, we
1089 # may end up trying to kill a process group other than the one
1090 # that we intend to kill. Therefore, we put the monitoring
1091 # process in the same process group as the child; that ensures
1092 # that the process group will persist until the monitoring
1093 # process kills it.
1094 self.__monitor_pid = os.fork()
1095 if self.__monitor_pid != 0:
1096 # Make sure that the monitoring process is placed into the
1097 # child's process group before the parent process calls
1098 # 'waitpid'. In this way, we are guaranteed that the process
1099 # group as the child
1100 os.setpgid(self.__monitor_pid, child_pid)
1101 else:
1102 # Put the monitoring process into the child's process
1103 # group. We know the process group still exists at
1104 # this point because either (a) we are in the process
1105 # group, or (b) the parent has not yet called waitpid.
1106 os.setpgid(0, child_pid)
1107
1108 # Close all open file descriptors. They are not needed
1109 # in the monitor process. Furthermore, when the parent
1110 # closes the write end of the stdin pipe to the child,
1111 # we do not want the pipe to remain open; leaving the
1112 # pipe open in the monitor process might cause the child
1113 # to block waiting for additional input.
1114 try:
1115 max_fds = os.sysconf("SC_OPEN_MAX")
1116 except:
1117 max_fds = 256
1118 for fd in xrange(max_fds):
1119 try:
1120 os.close(fd)
1121 except:
1122 pass
1123 try:
1124 if self.__timeout >= 0:
1125 # Give the child time to run.
1126 time.sleep(self.__timeout)
1127
1129 if sys.platform == "linux2": # we should be have /proc and gdb
1130 cmd = [
1131 "gdb",
1132 os.path.join("/proc", str(child_pid), "exe"),
1133 str(child_pid), "-batch", "-n", "-x",
1134 "'%s'" % os.path.join(
1135 os.path.dirname(__file__),
1136 "stack-trace.gdb")
1137 ]
1138 # FIXME: I wanted to use subprocess.Popen, but it doesn't want to work
1139 # in this context.
1140 o = os.popen(" ".join(cmd)).read()
1141 open(self.stack_trace_file, "w").write(o)
1142
1143
1144 # Kill all processes in the child process group.
1145 os.kill(0, signal.SIGKILL)
1146 else:
1147 # This call to select will never terminate.
1148 select.select([], [], [])
1149 finally:
1150 # Exit. This code is in a finally clause so that
1151 # we are guaranteed to get here no matter what.
1152 os._exit(0)
1153 elif self.__timeout >= 0 and sys.platform == "win32":
1154 # Create a monitoring thread.
1155 self.__monitor_thread = Thread(target=self.__Monitor)
1156 self.__monitor_thread.start()
1157
hivetimeline.read
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
IOTest.start
def start
Definition: IOTest.py:97

## Member Data Documentation

## ◆ __input

GaudiTest.GaudiFilterExecutable.__input
| private

Definition at line 1026 of file GaudiTest.py.

## ◆ __monitor_pid

GaudiTest.GaudiFilterExecutable.__monitor_pid
| private

Definition at line 1094 of file GaudiTest.py.

## ◆ __monitor_thread

GaudiTest.GaudiFilterExecutable.__monitor_thread
| private

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

Definition at line 1155 of file GaudiTest.py.

## ◆ __timeout

GaudiTest.GaudiFilterExecutable.__timeout
| private

Definition at line 1027 of file GaudiTest.py.

## ◆ stack_trace_file

GaudiTest.GaudiFilterExecutable.stack_trace_file

Definition at line 1028 of file GaudiTest.py.

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

- GaudiPolicy/qmtest_classes/GaudiTest.py