Skip to content

Commit

Permalink
Merge pull request #27 from Vizonex/uv-pipe-instead-of-uv-socketpair
Browse files Browse the repository at this point in the history
Add test_dealloc. Use uv_pipe to avoid bad fds.
  • Loading branch information
Vizonex authored May 27, 2024
2 parents d371490 + c34e2fe commit 806ca50
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
61 changes: 61 additions & 0 deletions tests/test_dealloc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import asyncio
import subprocess
import sys

from winloop import _testbase as tb


class TestDealloc(tb.UVTestCase):

def test_dealloc_1(self):
# Somewhere between Cython 0.25.2 and 0.26.0 uvloop programs
# started to trigger the following output:
#
# $ python prog.py
# Error in sys.excepthook:
#
# Original exception was:
#
# Upon some debugging, it appeared that Handle.__dealloc__ was
# called at a time where some CPython objects become non-functional,
# and any exception in __dealloc__ caused CPython to output the
# above.
#
# This regression test starts an event loop in debug mode,
# lets it run for a brief period of time, and exits the program.
# This will trigger Handle.__dealloc__, CallbackHandle.__dealloc__,
# and Loop.__dealloc__ methods. The test will fail if they produce
# any unwanted output.

async def test():
prog = '''\
import winloop as uvloop
async def foo():
return 42
def main():
loop = uvloop.new_event_loop()
loop.set_debug(True)
loop.run_until_complete(foo())
# Do not close the loop on purpose: let __dealloc__ methods run.
if __name__ == '__main__':
main()
'''

cmd = sys.executable
proc = await asyncio.create_subprocess_exec(
cmd, b'-W', b'ignore', b'-c', prog,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

await proc.wait()
out = await proc.stdout.read()
err = await proc.stderr.read()

return out, err

out, err = self.loop.run_until_complete(test())
self.assertEqual(out, b'', 'stdout is not empty')
self.assertEqual(err, b'', 'stderr is not empty')
11 changes: 6 additions & 5 deletions winloop/handles/process.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -802,13 +802,14 @@ cdef void __uvprocess_on_exit_callback(
cdef __socketpair():
cdef:
# Using uv.uv_os_sock_t for stability reasons...
uv.uv_os_sock_t fds[2]
# uv.uv_os_sock_t fds[2]
uv.uv_file fds[2]
int err

# TODO: Optimize uv_socket_pair function
# Added uv_socketpair instead my function since we kept seeing a bad file descriptor
err = uv.uv_socketpair(uv.SOCK_STREAM, 0, fds, uv.UV_NONBLOCK_PIPE, uv.UV_NONBLOCK_PIPE)

# err = uv.uv_socketpair(uv.SOCK_STREAM, 0, fds, uv.UV_NONBLOCK_PIPE, uv.UV_NONBLOCK_PIPE)
err = uv.uv_pipe(fds, uv.UV_NONBLOCK_PIPE, uv.UV_NONBLOCK_PIPE)

if err:
# TODO See if this is still correctly done or not...
Expand All @@ -821,8 +822,8 @@ cdef __socketpair():
# check here but optimized way down
# NOTE: Trying without assert will be faster...
# TODO Optimize guess handle down further using -> intptr_t __cdecl _get_osfhandle(int _FileHandle)
system._get_osfhandle(<int>fds[0])
system._get_osfhandle(<int>fds[1])
# system._get_osfhandle(<int>fds[0])
# system._get_osfhandle(<int>fds[1])

os_set_inheritable(fds[0], False)
os_set_inheritable(fds[1], False)
Expand Down
3 changes: 2 additions & 1 deletion winloop/includes/uv.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ cdef extern from "uv.h" nogil:


int uv_socketpair(int type, int protocol, uv_os_sock_t socket_vector[2], int flags0, int flags1)

int uv_pipe(uv_file fds[2], int read_flags, int write_flags)

uv_handle_type uv_guess_handle(uv_file)

cdef enum uv_fs_event:
Expand Down

0 comments on commit 806ca50

Please sign in to comment.