aboutsummaryrefslogtreecommitdiff
blob: 59ee5686d8127ace795b4b910c7571c01ccc7f60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import sys
from collections import deque

from portage import os
from _emerge.CompositeTask import CompositeTask
from _emerge.AsynchronousTask import AsynchronousTask

class TaskSequence(CompositeTask):
	"""
	A collection of tasks that executes sequentially. Each task
	must have a addExitListener() method that can be used as
	a means to trigger movement from one task to the next.
	"""

	__slots__ = ("_task_queue",)

	def __init__(self, **kwargs):
		AsynchronousTask.__init__(self, **kwargs)
		self._task_queue = deque()

	def add(self, task):
		self._task_queue.append(task)

	def _start(self):
		self._start_next_task()

	def _cancel(self):
		self._task_queue.clear()
		CompositeTask._cancel(self)

	def _start_next_task(self):
		try:
			task = self._task_queue.popleft()
		except IndexError:
			self._current_task = None
			self.returncode = os.EX_OK
			self.wait()
			return

		self._start_task(task, self._task_exit_handler)

	def _current_task_start_cb(self, future):
		CompositeTask._current_task_start_cb(self, future)
		if self.cancelled:
			self._task_queue.clear()

	def _task_exit_handler(self, task):
		if self._default_exit(task) != os.EX_OK:
			self.wait()
		elif self._task_queue:
			self._start_next_task()
		else:
			self._final_exit(task)
			self.wait()

	def __bool__(self):
		return bool(self._task_queue)

	if sys.hexversion < 0x3000000:
		__nonzero__ = __bool__

	def __len__(self):
		return len(self._task_queue)