* when EOF is received and data is still pending in incoming buffer,
the data will be lost before this fix
* also removed sleep from a recent-written test
When uvloop is run in the main thread we *always* want to set up a
self-pipe and a signal wakeup FD. That's the only way how libuv
can be notified that a ^C happened and break away from selecting
on sockets.
asyncio does not need to do that, as the 'selectors' module it uses
is already aware of the way Python implements ^C handling.
This translates to a slightly different behavior between asyncio &
uvloop:
1. uvloop needs to always call signal.set_wakeup_fd() when run in the
main thread;
2. asyncio only needs to call signal.set_wakeup_fd() when a user
registers a signal handler.
(2) means that if the user had not set up any signals, the signal
wakeup FD stays the same between different asyncio runs. This commit
fixes uvloop signal implementation to make sure that uvloop behaves
the same way as asyncio in regards to signal wakeup FD between the
loop runs. It also ensures that uvloop always have a proper
self-pipe set up so that ^C is always supported when it is run in
the main thread.
Issue #295.
Problem:
Uvloop for each loop register `atFork` handler that is called after fork is executed by forked child.
This handler works fine when fork was invoked by uvloop. In case fork is invoked by something else (such as external library)
uvloop freeze in this handler because:
- GIL is acquired inside `atFork` handler -> in case forked child does not contain python runtime `atFork` handler freeze at obtaining GIL
- when compiled in debug mode (`make debug`) cython trace calls are inserted inside compiled `atFork` handler -> in case forked child does not contain python runtime `atFork` handler freeze at providing trace call
Solution:
This fix solve described problems by implementing `atFork` handler as C function so that forked child can call it safely whether or not contains python runtime.
In 3.8 a lot of asyncio functions have their `loop` parameter
deprecated. So we change the semantics of uvloop tests to never
pass the loop explicitly (unless to Future objects, when necessary)
That means that we now also need to set up asyncio/uvloop loop policies
for tests in setUp hooks.
The functions `sys.set_coroutine_wrapper` and `sys.get_coroutine_wrapper`,
which were provisionally added to Python 3.5 and deprecated in Python 3.7,
are removed in Python 3.8.
uvloop doesn't use them since Python 3.7, but they remained defined
in stdlib.pxi, leading to AttributeErrors on Python 3.8+.
This makes the definition fallback to None if such functions don't exist.
Fixes https://github.com/MagicStack/uvloop/issues/251
* sendto() now tries to use uv_udp_try_send() first
* __convert_pyaddr_to_sockaddr() was optimized to maintain an
internal LRU cache of resolved addresses (quite an expensive
operation)
* Upgrade to libuv v1.28.0. This is the new minimal supported
libuv version.
* Switch from using uv_poll_t to uv_udp_t. This leads to
significant performance improvements.
The crux of the problem is that TimerHandle did not clean up a strong
reference from the event loop to `self`. This typically isn't a problem
unless there's another strong reference to the loop from the callback or
from its arguments (such as a Future).
A few new unit tests should ensure this kind of bugs won't happen again.
Fixes: #239.