| # Copyright 2010-2020 Gentoo Authors |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| from _emerge.AbstractPollTask import AbstractPollTask |
| |
| from portage import os |
| from portage.cache.mappings import slot_dict_class |
| |
| |
| class FifoIpcDaemon(AbstractPollTask): |
| |
| __slots__ = ("input_fifo", "output_fifo", "_files") |
| |
| _file_names = ("pipe_in",) |
| _files_dict = slot_dict_class(_file_names, prefix="") |
| |
| def _start(self): |
| self._files = self._files_dict() |
| |
| # File streams are in unbuffered mode since we do atomic |
| # read and write of whole pickles. |
| self._files.pipe_in = os.open(self.input_fifo, os.O_RDONLY | os.O_NONBLOCK) |
| |
| self.scheduler.add_reader(self._files.pipe_in, self._input_handler) |
| |
| self._registered = True |
| |
| def _reopen_input(self): |
| """ |
| Re-open the input stream, in order to suppress |
| POLLHUP events (bug #339976). |
| """ |
| self.scheduler.remove_reader(self._files.pipe_in) |
| os.close(self._files.pipe_in) |
| self._files.pipe_in = os.open(self.input_fifo, os.O_RDONLY | os.O_NONBLOCK) |
| |
| self.scheduler.add_reader(self._files.pipe_in, self._input_handler) |
| |
| def _cancel(self): |
| if self.returncode is None: |
| self.returncode = 1 |
| self._unregister() |
| # notify exit listeners |
| self._async_wait() |
| |
| def _input_handler(self): |
| raise NotImplementedError(self) |
| |
| def _unregister(self): |
| """ |
| Unregister from the scheduler and close open files. |
| """ |
| |
| self._registered = False |
| |
| if self._files is not None: |
| for f in self._files.values(): |
| self.scheduler.remove_reader(f) |
| os.close(f) |
| self._files = None |