pyuv: Assertion `loop->watchers[w->fd] == w' failed

The following code will abort pyuv by triggering the assertion:

src/unix/core.c:651: uv__io_stop: Assertion loop->watchers[w->fd] == w’ failed.`.

According to the libuv docs it is safe to close an FD after you stop() the poll handle. But even if it isn’t safe, I think pyuv should not abort the program. In case of a programming error, it should raise an exception.

import os
import pyuv

def on_write(handle, events, errno):
    pass

loop = pyuv.Loop.default_loop()
r1, w1 = os.pipe()
poll1 = pyuv.Poll(loop, w1)
poll1.start(pyuv.UV_WRITABLE, on_write)
loop.run_once()  # -> pipe is writable
poll1.stop()
os.close(r1); os.close(w1)
# libuv docs tell it's safe to close the FD after stop()

r2, w2 = os.pipe()
assert w1 == w2, 'Try again'
poll2 = pyuv.Poll(loop, w2)
poll2.start(pyuv.UV_WRITABLE, on_write)
loop.run_once()
poll1.close()  # -> crash
poll2.close()

About this issue

  • Original URL
  • State: closed
  • Created 12 years ago
  • Comments: 19 (16 by maintainers)

Commits related to this issue

Most upvoted comments

Multiplexing events? In uv-unix, that’s fairly easy to do. Not so in uv-win, apparently, but Bert said he’ll take patches.

I’m not against bringing the old behavior back but only if it’s consistent on all platforms.

I won’t be able to send patches, but I would like to point out that it is a real pain that libuv can only have one watcher per FD. I have cursed on libuv a couple of times 😃

Two examples.

  1. When integration an event loop into libdbus, the callback API expects that it can set multiple watches per FD. In practice, it only sets two watcher per FD: a reader and a writer (in separate calls).
  2. The new Python EventLoop (PEP3156) has separate add_reader() and add_writer() functions. So i need to track the FDs that are allocated when implementing this API for libuv here: https://github.com/geertj/looping