Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign up"Assertion `loop->watchers[w->fd] == w' failed." with multiprocessing and OS pipes #317
Comments
|
Thanks so much! I'll take a look in a few weeks when it's time for uvloop 0.15. If anyone wants to further debug & work on fix please go ahead! |
|
This seems to be a pretty serious issue - when the buffer is full writing to a pipe, this is 100% reproducible: import asyncio
from asyncio.subprocess import PIPE
import uvloop
async def main():
proc = await asyncio.create_subprocess_shell('sleep 3600', stdin=PIPE)
while True:
proc.stdin.write(b'x' * 32768)
await proc.stdin.drain()
if __name__ == '__main__':
uvloop.install()
asyncio.run(main())The error is the same:
Before we have a proper fix from libuv (I'll create a PR in libuv when time, refs libuv/libuv#2058), we can easily fix uvloop by partially reverting d8fe153 and adding this patch: diff --git a/uvloop/handles/pipe.pyx b/uvloop/handles/pipe.pyx
index 581554f..7a2c8ec 100644
--- a/uvloop/handles/pipe.pyx
+++ b/uvloop/handles/pipe.pyx
@@ -12,6 +12,7 @@ cdef __pipe_init_uv_handle(UVStream handle, Loop loop):
err = uv.uv_pipe_init(handle._loop.uvloop,
<uv.uv_pipe_t*>handle._handle,
0)
+ # UV_HANDLE_READABLE allows calling uv_read_start() on this pipe
+ # even if it is O_WRONLY, see also #317, libuv/libuv#2058
+ handle._handle.flags |= 0x00004000
if err < 0:
handle._abort_init()
raise convert_error(err)
diff --git a/uvloop/includes/uv.pxd b/uvloop/includes/uv.pxd
index 5f034b3..9efdab1 100644
--- a/uvloop/includes/uv.pxd
+++ b/uvloop/includes/uv.pxd
@@ -82,6 +82,7 @@ cdef extern from "uv.h" nogil:
ctypedef struct uv_handle_t:
void* data
uv_loop_t* loop
+ unsigned int flags
# ...
ctypedef struct uv_idle_t:But |
* in order to detect peer close on O_WRONLY pipe_t * refs libuv/libuv#2058 * refs MagicStack#317
* in order to detect peer close on O_WRONLY pipe_t * partially reverted d8fe153 * refs libuv/libuv#2058 * refs MagicStack#317 * fixes MagicStack#311, fixes MagicStack#312
* in order to detect peer close on O_WRONLY pipe_t * partially reverted d8fe153 * refs libuv/libuv#2058 * refs MagicStack#317 * fixes MagicStack#311, fixes MagicStack#312

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

Hi, I encountered the libuv assertion error while running multiprocessing and communicating with child processes via OS pipes.
I've prepared a minimal reproducible case.
I'm using kchmck/aiopipe to create pipes, which actually wraps file descriptors from
os.pipe()into asyncioStreamReaders/StreamWrites vialoop.connect_read_pipe()andloop.connect_write_pipe().Here, I have decapsulated wrapper classes from
aiopipeinto functions in theaiopipe_decap.pyfor easier code tracing.And here is the reproducible snippet, which creates a pipe connection between a child process and the master process. Once the child starts up, it will start a loop to send messages back to the master.
You can use the following environment variables to control some of the behaviors in this snippet.
U: enableuvloopif this variable is set (default:False)R: number of messages to send (default:1)M: content of messages (default:"a")Here's my result on my NAS (in Ubuntu 16.04 container). I found the assertion error related to the number of repeated times, the more the number is, the more chance to trigger the error. In the log shows that 9216 is a magic number but I doubt it's depending on different environments.
It works like a charm with vanilla asyncio.
With even larger number of repeated times.
R=100KR=1M0.14.0Python 3.7.3Linux-4.2.8-x86_64-with-debian-stretch-sid'PYTHONASYNCIODEBUGin env?: Yes