1
2
3
4 from _emerge.AsynchronousTask import AsynchronousTask
5 from portage import os
6
8
9 __slots__ = ("scheduler",) + ("_current_task",)
10
11 _TASK_QUEUED = -1
12
15
23
25 """
26 This does a loop calling self._current_task.poll()
27 repeatedly as long as the value of self._current_task
28 keeps changing. It calls poll() a maximum of one time
29 for a given self._current_task instance. This is useful
30 since calling poll() on a task can trigger advance to
31 the next task could eventually lead to the returncode
32 being set in cases when polling only a single task would
33 not have the same effect.
34 """
35
36 prev = None
37 while True:
38 task = self._current_task
39 if task is None or \
40 task is self._TASK_QUEUED or \
41 task is prev:
42
43 break
44 task.poll()
45 prev = task
46
47 return self.returncode
48
89
91 """
92 Raises an AssertionError if the given task is not the
93 same one as self._current_task. This can be useful
94 for detecting bugs.
95 """
96 if task is not self._current_task:
97 raise AssertionError("Unrecognized task: %s" % (task,))
98
100 """
101 Calls _assert_current() on the given task and then sets the
102 composite returncode attribute if task.returncode != os.EX_OK.
103 If the task failed then self._current_task will be set to None.
104 Subclasses can use this as a generic task exit callback.
105
106 @rtype: int
107 @return: The task.returncode attribute.
108 """
109 self._assert_current(task)
110 if task.returncode != os.EX_OK:
111 self.returncode = task.returncode
112 self._current_task = None
113 return task.returncode
114
116 """
117 Assumes that task is the final task of this composite task.
118 Calls _default_exit() and sets self.returncode to the task's
119 returncode and sets self._current_task to None.
120 """
121 self._default_exit(task)
122 self._current_task = None
123 self.returncode = task.returncode
124 return self.returncode
125
127 """
128 This calls _final_exit() and then wait().
129
130 Subclasses can use this as a generic final task exit callback.
131
132 """
133 self._final_exit(task)
134 return self.wait()
135
137 """
138 Register exit handler for the given task, set it
139 as self._current_task, and call task.start().
140
141 Subclasses can use this as a generic way to start
142 a task.
143
144 """
145 try:
146 task.scheduler = self.scheduler
147 except AttributeError:
148 pass
149 task.addExitListener(exit_handler)
150 self._current_task = task
151 task.start()
152
156
159
163