blob: 374497010c684950d155054dd44cda547170ce2c (
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# Copyright 2018-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = (
"AbstractChildWatcher",
"DefaultEventLoopPolicy",
)
import asyncio as _real_asyncio
from asyncio import events
from asyncio.unix_events import AbstractChildWatcher
import fcntl
import os
from portage.util._eventloop.global_event_loop import (
global_event_loop as _global_event_loop,
)
if hasattr(os, "set_blocking"):
def _set_nonblocking(fd):
os.set_blocking(fd, False)
else:
def _set_nonblocking(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
class _PortageEventLoopPolicy(events.AbstractEventLoopPolicy):
"""
Implementation of asyncio.AbstractEventLoopPolicy based on portage's
internal event loop. This supports running event loops in forks,
which is not supported by the default asyncio event loop policy,
see https://bugs.python.org/issue22087.
"""
def get_event_loop(self):
"""
Get the event loop for the current context.
Returns an event loop object implementing the AbstractEventLoop
interface.
@rtype: asyncio.AbstractEventLoop (or compatible)
@return: the current event loop policy
"""
return _global_event_loop()._asyncio_wrapper
def get_child_watcher(self):
"""Get the watcher for child processes."""
return _global_event_loop()._asyncio_child_watcher
class _AsyncioEventLoopPolicy(_PortageEventLoopPolicy):
"""
A subclass of _PortageEventLoopPolicy which raises
NotImplementedError if it is set as the real asyncio event loop
policy, since this class is intended to *wrap* the real asyncio
event loop policy.
"""
def _check_recursion(self):
if _real_asyncio.get_event_loop_policy() is self:
raise NotImplementedError("this class is only a wrapper")
def get_event_loop(self):
self._check_recursion()
return super().get_event_loop()
def get_child_watcher(self):
self._check_recursion()
return super().get_child_watcher()
DefaultEventLoopPolicy = _AsyncioEventLoopPolicy
|