├── setup.cfg ├── pyuv ├── _version.py └── __init__.py ├── dev-requirements.txt ├── tests ├── proc_basic.py ├── proc_infinite.py ├── proc_stdout.py ├── proc_args_stdout.py ├── proc_stdin_stdout.py ├── proc_env_stdout.py ├── test_tty.py ├── test_idle.py ├── test_prepare.py ├── test_gc.py ├── test_check.py ├── proc_ipc_echo.py ├── test_util.py ├── proc_ipc.py ├── benchmark-tcp.py ├── test_loop_handles.py ├── test_multihandles.py ├── test_signal.py ├── test_async.py ├── test_embed.py ├── test_loop.py ├── common.py ├── test_dns.py ├── test_basetype.py ├── test_timer.py ├── test_threadpool.py └── test_poll.py ├── TODO ├── tox.ini ├── docs ├── TODO.rst ├── errno.rst ├── pyuv.rst ├── examples.rst ├── signal.rst ├── check.rst ├── prepare.rst ├── refcount.rst ├── async.rst ├── idle.rst ├── dns.rst ├── timer.rst ├── handle.rst ├── index.rst ├── thread.rst ├── error.rst ├── util.rst ├── poll.rst ├── tty.rst ├── loop.rst └── process.rst ├── .gitignore ├── make-manylinux ├── MANIFEST.in ├── AUTHORS ├── .travis.yml ├── examples ├── echo-server-udp.py ├── signal_wakeup.py ├── echo-pipe.py ├── echo-tty.py ├── echo-server-tcp.py └── filesystem_watch.py ├── LICENSE ├── .travis └── before_install.sh ├── deps └── libuv │ ├── src │ ├── win │ │ ├── detect-wakeup.c │ │ ├── req.c │ │ ├── snprintf.c │ │ ├── stream-inl.h │ │ ├── atomicops-inl.h │ │ ├── async.c │ │ ├── dl.c │ │ ├── handle.c │ │ └── getnameinfo.c │ ├── unix │ │ ├── posix-hrtime.c │ │ ├── sysinfo-loadavg.c │ │ ├── no-proctitle.c │ │ ├── procfs-exepath.c │ │ ├── sysinfo-memory.c │ │ ├── no-fsevents.c │ │ ├── cygwin.c │ │ ├── spinlock.h │ │ ├── pthread-fixes.c │ │ ├── dl.c │ │ ├── os390-syscalls.h │ │ ├── pthread-barrier.c │ │ ├── proctitle.c │ │ ├── atomic-ops.h │ │ ├── poll.c │ │ ├── getnameinfo.c │ │ ├── loop-watcher.c │ │ └── bsd-ifaddrs.c │ └── version.c │ └── include │ ├── uv-os390.h │ ├── uv-threadpool.h │ ├── uv-posix.h │ ├── uv-aix.h │ ├── uv-bsd.h │ ├── uv-linux.h │ ├── uv-version.h │ ├── android-ifaddrs.h │ ├── uv-sunos.h │ ├── pthread-barrier.h │ └── uv-darwin.h ├── setup.py ├── tasks.py ├── src ├── errno.c ├── error.c └── abstract.c ├── appveyor.yml ├── README.rst └── appveyor ├── run_with_env.cmd └── install.ps1 /setup.cfg: -------------------------------------------------------------------------------- 1 | [nosetests] 2 | where=tests 3 | -------------------------------------------------------------------------------- /pyuv/_version.py: -------------------------------------------------------------------------------- 1 | 2 | __version__ = "1.4.0" 3 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | nose 2 | sphinx 3 | sphinx-autobuild 4 | -------------------------------------------------------------------------------- /tests/proc_basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | test = None 4 | 5 | -------------------------------------------------------------------------------- /pyuv/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ._cpyuv import * 3 | from ._version import __version__ 4 | 5 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | - Better docstrings! 3 | 4 | Issue tracker: https://github.com/saghul/pyuv/issues 5 | 6 | -------------------------------------------------------------------------------- /tests/proc_infinite.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import sleep 4 | 5 | while True: 6 | test = None 7 | sleep(1) 8 | 9 | -------------------------------------------------------------------------------- /tests/proc_stdout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | import sys 6 | 7 | print("TEST") 8 | sys.stdout.flush() 9 | 10 | -------------------------------------------------------------------------------- /tests/proc_args_stdout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | import sys 6 | 7 | print(sys.argv[1]) 8 | sys.stdout.flush() 9 | 10 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27, py33, py34, py35, py36, pypy, pypy3 3 | 4 | [testenv] 5 | setenv = 6 | PYUV_INSIDE_TOX = 1 7 | deps = nose 8 | commands = nosetests -v [] 9 | 10 | -------------------------------------------------------------------------------- /tests/proc_stdin_stdout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | import sys 6 | 7 | c = sys.stdin.readline() 8 | print(c) 9 | sys.stdout.flush() 10 | 11 | -------------------------------------------------------------------------------- /docs/TODO.rst: -------------------------------------------------------------------------------- 1 | .. _TODO: 2 | 3 | 4 | .. title:: ToDo 5 | 6 | .. currentmodule:: pyuv 7 | 8 | 9 | Things yet to be done 10 | ********************* 11 | 12 | .. literalinclude:: ../TODO 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/proc_env_stdout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | import os 6 | import sys 7 | 8 | print(os.environ.get("TEST", "FAIL")) 9 | sys.stdout.flush() 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #python specific 2 | *.pyc 3 | *.so 4 | *.pyd 5 | build/* 6 | dist/* 7 | MANIFEST 8 | __pycache__/ 9 | *.egg-info/ 10 | 11 | ## generic files to ignore 12 | *~ 13 | *.lock 14 | *.DS_Store 15 | *.swp 16 | *.swo 17 | *.out 18 | 19 | .tox/ 20 | docs/_build/ 21 | 22 | wheelhouse/ 23 | wheeltmp/ 24 | -------------------------------------------------------------------------------- /make-manylinux: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Clean tree 5 | git clean -dfx 6 | 7 | # 64 bits 8 | docker run --rm -ti -v "$(pwd):/pyuv" quay.io/pypa/manylinux1_x86_64 /pyuv/build-manylinux-wheels.sh 9 | 10 | # 32 bits 11 | docker run --rm -ti -v "$(pwd):/pyuv" quay.io/pypa/manylinux1_i686 linux32 /pyuv/build-manylinux-wheels.sh 12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS README.rst LICENSE TODO ChangeLog 2 | include build_inplace setup.py setup_libuv.py setup.cfg tox.ini 3 | recursive-include docs * 4 | recursive-include examples * 5 | recursive-include patches * 6 | recursive-include src * 7 | recursive-include tests * 8 | recursive-include deps * 9 | recursive-exclude * __pycache__ 10 | recursive-exclude * *.py[co] 11 | prune docs/_build 12 | 13 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Main author 2 | Saúl Ibarra Corretgé 3 | 4 | # Contributors - thank you all! 5 | Bruce Mitchener (@waywardmonkeys) 6 | Andrew Tolbert 7 | Richard M. Tew (@rmtew) 8 | tanbro (@tanbro) 9 | Masahito Nakamura 10 | Romuald Brunet 11 | Geert Jansen 12 | Benoit Chesneau 13 | Marc Schlaich (@schlamar) 14 | ayanamist (@ayanamist) 15 | Lipin Dmitriy (lipindd@gdeetotdom.ru) 16 | Remy Blank (@rblank) 17 | Iyed Bennour (@iyedb) 18 | 19 | -------------------------------------------------------------------------------- /tests/test_tty.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import unittest 4 | 5 | from common import platform_skip, TestCase 6 | import pyuv 7 | 8 | 9 | @platform_skip(["win32"]) 10 | class TYTest(TestCase): 11 | 12 | def test_tty1(self): 13 | tty = pyuv.TTY(self.loop, sys.stdin.fileno(), True) 14 | w, h = tty.get_winsize() 15 | self.assertNotEqual((w, h), (None, None)) 16 | 17 | tty.close() 18 | 19 | self.loop.run() 20 | tty.reset_mode() 21 | 22 | 23 | if __name__ == '__main__': 24 | unittest.main(verbosity=2) 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | python: 4 | - '2.7' 5 | - '3.3' 6 | - '3.4' 7 | - '3.5' 8 | - '3.6' 9 | - '3.7-dev' 10 | - 'pypy' 11 | - 'pypy3' 12 | 13 | branches: 14 | only: 15 | - master 16 | - v1.x 17 | 18 | cache: pip 19 | before_install: 20 | - source .travis/before_install.sh 21 | install: 22 | - python --version 23 | - pip --version 24 | - pip install tox 25 | script: 26 | - tox -e py 27 | 28 | notifications: 29 | email: 30 | on_success: never 31 | on_failure: change 32 | -------------------------------------------------------------------------------- /tests/test_idle.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class IdleTest(TestCase): 9 | 10 | def test_idle1(self): 11 | self.idle_cb_called = 0 12 | def idle_cb(idle): 13 | self.idle_cb_called += 1 14 | idle.stop() 15 | idle.close() 16 | idle = pyuv.Idle(self.loop) 17 | idle.start(idle_cb) 18 | self.loop.run() 19 | self.assertEqual(self.idle_cb_called, 1) 20 | 21 | 22 | if __name__ == '__main__': 23 | unittest.main(verbosity=2) 24 | -------------------------------------------------------------------------------- /tests/test_prepare.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class PrepareTest(TestCase): 9 | 10 | def test_prepare1(self): 11 | self.prepare_cb_called = 0 12 | def prepare_cb(prepare): 13 | self.prepare_cb_called += 1 14 | prepare.stop() 15 | prepare.close() 16 | prepare = pyuv.Prepare(self.loop) 17 | prepare.start(prepare_cb) 18 | self.loop.run() 19 | self.assertEqual(self.prepare_cb_called, 1) 20 | 21 | 22 | if __name__ == '__main__': 23 | unittest.main(verbosity=2) 24 | -------------------------------------------------------------------------------- /tests/test_gc.py: -------------------------------------------------------------------------------- 1 | 2 | import gc 3 | import unittest 4 | import weakref 5 | 6 | from common import TestCase 7 | import pyuv 8 | 9 | 10 | class Foo(object): pass 11 | 12 | class GCTest(TestCase): 13 | 14 | def test_gc(self): 15 | timer = pyuv.Timer(self.loop) 16 | 17 | w_timer = weakref.ref(timer) 18 | self.assertNotEqual(w_timer(), None) 19 | 20 | foo = Foo() 21 | foo.timer = timer 22 | timer.foo = foo 23 | 24 | timer = None 25 | foo = None 26 | 27 | gc.collect() 28 | self.assertEqual(w_timer(), None) 29 | 30 | 31 | if __name__ == '__main__': 32 | unittest.main(verbosity=2) 33 | -------------------------------------------------------------------------------- /examples/echo-server-udp.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import signal 5 | import pyuv 6 | 7 | 8 | def on_read(handle, ip_port, flags, data, error): 9 | if data is not None: 10 | handle.send(ip_port, data) 11 | 12 | def signal_cb(handle, signum): 13 | signal_h.close() 14 | server.close() 15 | 16 | 17 | print("PyUV version %s" % pyuv.__version__) 18 | 19 | loop = pyuv.Loop.default_loop() 20 | 21 | server = pyuv.UDP(loop) 22 | server.bind(("0.0.0.0", 1234)) 23 | server.start_recv(on_read) 24 | 25 | signal_h = pyuv.Signal(loop) 26 | signal_h.start(signal_cb, signal.SIGINT) 27 | 28 | loop.run() 29 | 30 | print("Stopped!") 31 | 32 | -------------------------------------------------------------------------------- /docs/errno.rst: -------------------------------------------------------------------------------- 1 | .. _errno: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | =================================================== 8 | :py:mod:`pyuv.errno` --- Error constant definitions 9 | =================================================== 10 | 11 | 12 | This module contains the defined error constants from libuv and c-ares. 13 | 14 | **IMPORTANT:** The errno codes in pyuv don't necessarily match those in the 15 | Python `errno` module. 16 | 17 | .. py:attribute:: pyuv.errno.errorcode 18 | 19 | Mapping (code, string) with libuv error codes. 20 | 21 | .. py:function:: pyuv.errno.strerror(errorno) 22 | 23 | :param int errorno: Error number. 24 | 25 | Get the string representation of the given error number. 26 | 27 | -------------------------------------------------------------------------------- /docs/pyuv.rst: -------------------------------------------------------------------------------- 1 | .. _pyuv: 2 | 3 | 4 | ********************************************* 5 | :py:mod:`pyuv` --- Python interface to libuv. 6 | ********************************************* 7 | 8 | .. py:module:: pyuv 9 | :platform: POSIX, Windows 10 | :synopsis: Python interface to linuv. 11 | 12 | .. seealso:: 13 | `libuv's source code 14 | `_. 15 | 16 | 17 | Objects 18 | ******* 19 | 20 | .. toctree:: 21 | :maxdepth: 2 22 | :titlesonly: 23 | 24 | loop 25 | handle 26 | timer 27 | tcp 28 | udp 29 | pipe 30 | tty 31 | poll 32 | process 33 | async 34 | prepare 35 | idle 36 | check 37 | signal 38 | dns 39 | fs 40 | error 41 | errno 42 | thread 43 | util 44 | 45 | -------------------------------------------------------------------------------- /examples/signal_wakeup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import pyuv 5 | import signal 6 | import socket 7 | 8 | 9 | reader, writer = socket.socketpair() 10 | reader.setblocking(False) 11 | writer.setblocking(False) 12 | 13 | def prepare_cb(handle): 14 | print("Inside prepare_cb") 15 | 16 | def excepthook(typ, val, tb): 17 | print("Inside excepthook") 18 | if typ is KeyboardInterrupt: 19 | prepare.stop() 20 | signal_checker.stop() 21 | 22 | loop = pyuv.Loop.default_loop() 23 | loop.excepthook = excepthook 24 | prepare = pyuv.Prepare(loop) 25 | prepare.start(prepare_cb) 26 | 27 | signal.set_wakeup_fd(writer.fileno()) 28 | signal_checker = pyuv.util.SignalChecker(loop, reader.fileno()) 29 | signal_checker.start() 30 | 31 | loop.run() 32 | 33 | -------------------------------------------------------------------------------- /docs/examples.rst: -------------------------------------------------------------------------------- 1 | .. _examples: 2 | 3 | 4 | .. title:: Examples 5 | 6 | .. currentmodule:: pyuv 7 | 8 | 9 | UDP Echo server 10 | *************** 11 | 12 | .. literalinclude:: ../examples/echo-server-udp.py 13 | 14 | 15 | TCP Echo server 16 | *************** 17 | 18 | .. literalinclude:: ../examples/echo-server-tcp.py 19 | 20 | 21 | TCP Echo server using Poll handles 22 | ********************************** 23 | 24 | .. literalinclude:: ../examples/echo-server-poll.py 25 | 26 | 27 | Standard IO Echo server using Pipe handles 28 | ****************************************** 29 | 30 | .. literalinclude:: ../examples/echo-pipe.py 31 | 32 | 33 | Standard IO Echo server using TTY handles 34 | ***************************************** 35 | 36 | .. literalinclude:: ../examples/echo-tty.py 37 | 38 | -------------------------------------------------------------------------------- /examples/echo-pipe.py: -------------------------------------------------------------------------------- 1 | import signal 2 | import sys 3 | import pyuv 4 | 5 | 6 | def on_pipe_read(handle, data, error): 7 | if data is None or data == b"exit": 8 | pipe_stdin.close() 9 | pipe_stdout.close() 10 | else: 11 | pipe_stdout.write(data) 12 | 13 | def signal_cb(handle, signum): 14 | if not pipe_stdin.closed: 15 | pipe_stdin.close() 16 | if not pipe_stdin.closed: 17 | pipe_stdout.close() 18 | signal_h.close() 19 | 20 | 21 | loop = pyuv.Loop.default_loop() 22 | 23 | pipe_stdin = pyuv.Pipe(loop) 24 | pipe_stdin.open(sys.stdin.fileno()) 25 | pipe_stdin.start_read(on_pipe_read) 26 | 27 | pipe_stdout = pyuv.Pipe(loop) 28 | pipe_stdout.open(sys.stdout.fileno()) 29 | 30 | signal_h = pyuv.Signal(loop) 31 | signal_h.start(signal_cb, signal.SIGINT) 32 | 33 | loop.run() 34 | 35 | -------------------------------------------------------------------------------- /tests/test_check.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class CheckTest(TestCase): 9 | 10 | def test_check1(self): 11 | self.check_cb_called = 0 12 | def check_cb(check): 13 | self.check_cb_called += 1 14 | check.stop() 15 | check.close() 16 | self.timer_cb_called = 0 17 | def timer_cb(timer): 18 | self.timer_cb_called += 1 19 | timer.stop() 20 | timer.close() 21 | check = pyuv.Check(self.loop) 22 | check.start(check_cb) 23 | timer = pyuv.Timer(self.loop) 24 | timer.start(timer_cb, 0.1, 0) 25 | self.loop.run() 26 | self.assertEqual(self.check_cb_called, 1) 27 | 28 | 29 | if __name__ == '__main__': 30 | unittest.main(verbosity=2) 31 | -------------------------------------------------------------------------------- /examples/echo-tty.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import signal 5 | import sys 6 | import pyuv 7 | 8 | 9 | def on_tty_read(handle, data, error): 10 | if data is None or data == b"exit": 11 | tty_stdin.close() 12 | tty_stdout.close() 13 | else: 14 | tty_stdout.write(data) 15 | 16 | def signal_cb(handle, signum): 17 | tty_stdin.close() 18 | tty_stdout.close() 19 | signal_h.close() 20 | 21 | 22 | loop = pyuv.Loop.default_loop() 23 | 24 | tty_stdin = pyuv.TTY(loop, sys.stdin.fileno(), True) 25 | tty_stdin.start_read(on_tty_read) 26 | tty_stdout = pyuv.TTY(loop, sys.stdout.fileno(), False) 27 | 28 | if sys.platform != "win32": 29 | print("Window size: (%d, %d)" % tty_stdin.get_winsize()) 30 | 31 | signal_h = pyuv.Signal(loop) 32 | signal_h.start(signal_cb, signal.SIGINT) 33 | 34 | loop.run() 35 | 36 | pyuv.TTY.reset_mode() 37 | 38 | -------------------------------------------------------------------------------- /examples/echo-server-tcp.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import signal 5 | import pyuv 6 | 7 | 8 | def on_read(client, data, error): 9 | if data is None: 10 | client.close() 11 | clients.remove(client) 12 | return 13 | client.write(data) 14 | 15 | def on_connection(server, error): 16 | client = pyuv.TCP(server.loop) 17 | server.accept(client) 18 | clients.append(client) 19 | client.start_read(on_read) 20 | 21 | def signal_cb(handle, signum): 22 | [c.close() for c in clients] 23 | signal_h.close() 24 | server.close() 25 | 26 | 27 | print("PyUV version %s" % pyuv.__version__) 28 | 29 | loop = pyuv.Loop.default_loop() 30 | clients = [] 31 | 32 | server = pyuv.TCP(loop) 33 | server.bind(("0.0.0.0", 1234)) 34 | server.listen(on_connection) 35 | 36 | signal_h = pyuv.Signal(loop) 37 | signal_h.start(signal_cb, signal.SIGINT) 38 | 39 | loop.run() 40 | print("Stopped!") 41 | 42 | -------------------------------------------------------------------------------- /docs/signal.rst: -------------------------------------------------------------------------------- 1 | .. _signal: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ==================================== 8 | :py:class:`Signal` --- Signal handle 9 | ==================================== 10 | 11 | 12 | .. py:class:: Signal(loop) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Signal.loop`). 16 | 17 | ``Signal`` handles register for the specified signal and notify the use about the signal's 18 | occurrence through the specified callback. 19 | 20 | 21 | .. py:method:: start(callback, signum) 22 | 23 | :param callable callback: Function that will be called when the specified signal is received. 24 | 25 | :param int signum: Specific signal that this handle listens to. 26 | 27 | Start the ``Signal`` handle. 28 | 29 | Callback signature: ``callback(signal_handle, signal_num)``. 30 | 31 | .. py:method:: stop 32 | 33 | Stop the ``Signal`` handle. 34 | 35 | -------------------------------------------------------------------------------- /docs/check.rst: -------------------------------------------------------------------------------- 1 | .. _check: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ================================== 8 | :py:class:`Check` --- Check handle 9 | ================================== 10 | 11 | 12 | .. py:class:: Check(loop) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Check.loop`). 16 | 17 | ``Check`` handles are usually used together with :py:class:`Prepare` handles. 18 | They run just after the event loop comes back after being blocked for I/O. The 19 | callback will be called *once* each loop iteration, after I/O. 20 | 21 | 22 | .. py:method:: start(callback) 23 | 24 | :param callable callback: Function that will be called when the ``Check`` 25 | handle is run by the event loop. 26 | 27 | Start the ``Check`` handle. 28 | 29 | Callback signature: ``callback(check_handle)``. 30 | 31 | .. py:method:: stop 32 | 33 | Stop the ``Check`` handle. 34 | 35 | -------------------------------------------------------------------------------- /docs/prepare.rst: -------------------------------------------------------------------------------- 1 | .. _prepare: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ====================================== 8 | :py:class:`Prepare` --- Prepare handle 9 | ====================================== 10 | 11 | 12 | .. py:class:: Prepare(loop) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Prepare.loop`). 16 | 17 | ``Prepare`` handles are usually used together with :py:class:`Check` handles. 18 | They run just before the event loop ia about to block for I/O. The callback will be 19 | called *once* each loop iteration, before I/O. 20 | 21 | .. py:method:: start(callback) 22 | 23 | :param callable callback: Function that will be called when the ``Prepare`` 24 | handle is run by the event loop. 25 | 26 | Start the ``Prepare`` handle. 27 | 28 | Callback signature: ``callback(prepare_handle)``. 29 | 30 | .. py:method:: stop 31 | 32 | Stop the ``Prepare`` handle. 33 | 34 | -------------------------------------------------------------------------------- /tests/proc_ipc_echo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.insert(0, '../') 5 | 6 | import pyuv 7 | 8 | 9 | def on_write(handle, error): 10 | global channel, recv_handle 11 | recv_handle.close() 12 | channel.close() 13 | 14 | def on_channel_read(handle, data, error): 15 | global channel, loop, recv_handle 16 | pending = channel.pending_handle_type() 17 | assert pending in (pyuv.UV_NAMED_PIPE, pyuv.UV_UDP, pyuv.UV_TCP), "wrong handle type" 18 | if pending == pyuv.UV_NAMED_PIPE: 19 | recv_handle = pyuv.Pipe(loop) 20 | elif pending == pyuv.UV_TCP: 21 | recv_handle = pyuv.TCP(loop) 22 | elif pending == pyuv.UV_UDP: 23 | recv_handle = pyuv.UDP(loop) 24 | channel.accept(recv_handle) 25 | channel.write(b".", on_write, recv_handle) 26 | 27 | 28 | loop = pyuv.Loop.default_loop() 29 | 30 | recv_handle = None 31 | 32 | channel = pyuv.Pipe(loop, True) 33 | channel.open(sys.stdin.fileno()) 34 | channel.start_read(on_channel_read) 35 | 36 | loop.run() 37 | 38 | -------------------------------------------------------------------------------- /docs/refcount.rst: -------------------------------------------------------------------------------- 1 | .. _refcount: 2 | 3 | 4 | ************************* 5 | Reference counting scheme 6 | ************************* 7 | 8 | (This section is about the reference counting scheme used by libuv, it's not related in any 9 | way to the reference counting model used by CPython) 10 | 11 | The event loop runs (when `Loop.run` is called) until there are no more active handles. What 12 | does it mean for a handle to be 'active'? Depends on the handle type: 13 | 14 | * Timers: active when ticking 15 | * Sockets (TCP, UDP, Pipe, TTY): active when reading, writing or listening 16 | * Process: active until the child process dies 17 | * Idle, Prepare, Check, Poll, FSEvent, FSPoll: active once they are started 18 | * Async: always active, until closed 19 | 20 | All handles have the `ref` read-write property available in order to modify the default behavior. 21 | These functions operate at the handle level (that is, the *handle* is referenced, not the loop) so if a 22 | handle is ref'd it will maintain the loop alive even if not active. 23 | 24 | -------------------------------------------------------------------------------- /docs/async.rst: -------------------------------------------------------------------------------- 1 | .. _async: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ================================== 8 | :py:class:`Async` --- Async handle 9 | ================================== 10 | 11 | 12 | .. py:class:: Async(loop, callback) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Async.loop`). 16 | 17 | :param callable callback: Function that will be called after the ``Async`` handle fires. It will 18 | be called in the event loop. 19 | 20 | Calling event loop related functions from an outside thread is not safe in general. 21 | This is actually the only handle which is thread safe. The ``Async`` handle may 22 | be used to pass control from an outside thread to the event loop, as it will allow 23 | the calling thread to schedule a callback which will be called in the event loop 24 | thread. 25 | 26 | 27 | .. py:method:: send() 28 | 29 | Start the ``Async`` handle. The callback will be called *at least* once. 30 | 31 | Callback signature: ``callback(async_handle)`` 32 | 33 | -------------------------------------------------------------------------------- /tests/test_util.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class UtilTest(TestCase): 9 | 10 | def test_hrtime(self): 11 | r = pyuv.util.hrtime() 12 | self.assertTrue(r) 13 | 14 | def test_freemem(self): 15 | r = pyuv.util.get_free_memory() 16 | self.assertTrue(r) 17 | 18 | def test_totalmem(self): 19 | r = pyuv.util.get_total_memory() 20 | self.assertTrue(r) 21 | 22 | def test_loadavg(self): 23 | r = pyuv.util.loadavg() 24 | self.assertTrue(r) 25 | 26 | def test_uptime(self): 27 | r = pyuv.util.uptime() 28 | self.assertTrue(r) 29 | 30 | def test_resident_set_memory(self): 31 | r = pyuv.util.resident_set_memory() 32 | self.assertTrue(r) 33 | 34 | def test_interface_addresses(self): 35 | r = pyuv.util.interface_addresses() 36 | self.assertTrue(r) 37 | 38 | def test_cpu_info(self): 39 | r = pyuv.util.cpu_info() 40 | self.assertTrue(r) 41 | 42 | 43 | if __name__ == '__main__': 44 | unittest.main(verbosity=2) 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 by Saúl Ibarra Corretgé 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /tests/proc_ipc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.insert(0, '../') 5 | 6 | import pyuv 7 | 8 | 9 | def on_channel_write(handle, error): 10 | global channel, tcp_server 11 | channel.close() 12 | tcp_server.close() 13 | 14 | def on_ipc_connection(handle, error): 15 | global channel, connection_accepted, loop, tcp_server 16 | if connection_accepted: 17 | return 18 | conn = pyuv.TCP(loop) 19 | tcp_server.accept(conn) 20 | conn.close() 21 | channel.write(b"accepted_connection", on_channel_write) 22 | connection_accepted = True 23 | 24 | 25 | connection_accepted = False 26 | listen_after_write = sys.argv[1] == "listen_after_write" 27 | port = int(sys.argv[2]) 28 | 29 | loop = pyuv.Loop.default_loop() 30 | 31 | channel = pyuv.Pipe(loop, True) 32 | channel.open(sys.stdin.fileno()) 33 | 34 | tcp_server = pyuv.TCP(loop) 35 | tcp_server.bind(("0.0.0.0", port)) 36 | if not listen_after_write: 37 | tcp_server.listen(on_ipc_connection, 12) 38 | 39 | channel.write(b"hello", None, tcp_server) 40 | 41 | if listen_after_write: 42 | tcp_server.listen(on_ipc_connection, 12) 43 | 44 | loop.run() 45 | 46 | -------------------------------------------------------------------------------- /.travis/before_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cd $HOME 5 | 6 | if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then 7 | deactivate 8 | 9 | wget https://bitbucket.org/squeaky/portable-pypy/downloads/pypy-5.8-linux_x86_64-portable.tar.bz2 10 | tar -jxvf pypy-5.8-linux_x86_64-portable.tar.bz2 11 | cd pypy-5.8-linux_x86_64-portable 12 | 13 | echo 'Setting up aliases...' 14 | export PATH=$HOME/pypy-5.8-linux_x86_64-portable/bin/:$PATH 15 | ln -s ~/pypy-5.8-linux_x86_64-portable/bin/pypy bin/python 16 | 17 | echo 'Setting up pip...' 18 | bin/pypy -m ensurepip 19 | fi 20 | 21 | if [[ $TRAVIS_PYTHON_VERSION == 'pypy3' ]]; then 22 | deactivate 23 | 24 | wget https://bitbucket.org/squeaky/portable-pypy/downloads/pypy3.5-5.8-beta-linux_x86_64-portable.tar.bz2 25 | tar -jxvf pypy3.5-5.8-beta-linux_x86_64-portable.tar.bz2 26 | cd pypy3.5-5.8-beta-linux_x86_64-portable 27 | 28 | echo 'Setting up aliases...' 29 | export PATH=$HOME/pypy3.5-5.8-beta-linux_x86_64-portable/bin/:$PATH 30 | ln -s ~/pypy3.5-5.8-beta-linux_x86_64-portable/bin/pypy3.5 bin/python 31 | 32 | echo 'Setting up pip...' 33 | bin/pypy -m ensurepip 34 | ln -s ~/pypy3.5-5.8-beta-linux_x86_64-portable/bin/pip3.5 bin/pip 35 | fi 36 | 37 | cd $TRAVIS_BUILD_DIR 38 | -------------------------------------------------------------------------------- /deps/libuv/src/win/detect-wakeup.c: -------------------------------------------------------------------------------- 1 | #include "uv.h" 2 | #include "internal.h" 3 | #include "winapi.h" 4 | 5 | static void uv__register_system_resume_callback(void); 6 | 7 | void uv__init_detect_system_wakeup(void) { 8 | /* Try registering system power event callback. This is the cleanest 9 | * method, but it will only work on Win8 and above. 10 | */ 11 | uv__register_system_resume_callback(); 12 | } 13 | 14 | static ULONG CALLBACK uv__system_resume_callback(PVOID Context, 15 | ULONG Type, 16 | PVOID Setting) { 17 | if (Type == PBT_APMRESUMESUSPEND || Type == PBT_APMRESUMEAUTOMATIC) 18 | uv__wake_all_loops(); 19 | 20 | return 0; 21 | } 22 | 23 | static void uv__register_system_resume_callback(void) { 24 | _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient; 25 | _HPOWERNOTIFY registration_handle; 26 | 27 | if (pPowerRegisterSuspendResumeNotification == NULL) 28 | return; 29 | 30 | recipient.Callback = uv__system_resume_callback; 31 | recipient.Context = NULL; 32 | (*pPowerRegisterSuspendResumeNotification)(DEVICE_NOTIFY_CALLBACK, 33 | &recipient, 34 | ®istration_handle); 35 | } 36 | -------------------------------------------------------------------------------- /deps/libuv/src/win/req.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include 23 | 24 | #include "uv.h" 25 | #include "internal.h" 26 | -------------------------------------------------------------------------------- /docs/idle.rst: -------------------------------------------------------------------------------- 1 | .. _idle: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ================================ 8 | :py:class:`Idle` --- Idle handle 9 | ================================ 10 | 11 | 12 | .. py:class:: Idle(loop) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Idle.loop`). 16 | 17 | ``Idle`` handles will run the given callback *once per loop iteration*, right 18 | before the :py:class:`Prepare` handles. 19 | 20 | .. note:: 21 | The notable difference with :py:class:`Prepare` handles is that 22 | when there are active :py:class:`Idle` handles, the loop will perform 23 | a zero timeout poll instead of blocking for I/O. 24 | 25 | .. warning:: 26 | Despite the name, :py:class:`Idle` handles will get their callbacks 27 | called on **every** loop iteration, not when the loop is actually 28 | "idle". 29 | 30 | 31 | .. py:method:: start(callback) 32 | 33 | :param callable callback: Function that will be called when the ``Idle`` 34 | handle is run by the event loop. 35 | 36 | Start the ``Idle`` handle. 37 | 38 | Callback signature: ``callback(idle_handle)``. 39 | 40 | .. py:method:: stop 41 | 42 | Stop the ``Idle`` handle. 43 | 44 | -------------------------------------------------------------------------------- /examples/filesystem_watch.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import pyuv 5 | import signal 6 | import sys 7 | import os 8 | import optparse 9 | 10 | 11 | def fsevent_callback(fsevent_handle, filename, events, error): 12 | if error is not None: 13 | txt = 'error %s: %s' % (error, pyuv.errno.strerror(error)) 14 | else: 15 | evts = [] 16 | if events & pyuv.fs.UV_RENAME: 17 | evts.append('rename') 18 | if events & pyuv.fs.UV_CHANGE: 19 | evts.append('change') 20 | txt = 'events: %s' % ', '.join(evts) 21 | print('file: %s, %s' % (filename, txt)) 22 | 23 | 24 | def sig_cb(handle, signum): 25 | handle.close() 26 | 27 | 28 | def main(path): 29 | loop = pyuv.Loop.default_loop() 30 | try: 31 | fsevents = pyuv.fs.FSEvent(loop) 32 | fsevents.start(path, 0, fsevent_callback) 33 | fsevents.ref = False 34 | except pyuv.error.FSEventError as e: 35 | print('error: %s' % e) 36 | sys.exit(2) 37 | signal_h = pyuv.Signal(loop) 38 | signal_h.start(sig_cb, signal.SIGINT) 39 | print('Watching path %s' % os.path.abspath(path)) 40 | loop.run() 41 | 42 | 43 | if __name__ == '__main__': 44 | parser = optparse.OptionParser() 45 | parser.add_option('-p', '--path', help='a path to watch', default='.') 46 | opts, args = parser.parse_args() 47 | main(opts.path) 48 | 49 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-os390.h: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_MVS_H 23 | #define UV_MVS_H 24 | 25 | #define UV_PLATFORM_SEM_T int 26 | 27 | #define UV_PLATFORM_LOOP_FIELDS \ 28 | void* ep; \ 29 | 30 | #endif /* UV_MVS_H */ 31 | -------------------------------------------------------------------------------- /docs/dns.rst: -------------------------------------------------------------------------------- 1 | .. _dns: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | =============================================================== 8 | :py:mod:`puyv.dns` --- Asynchronous getaddrinfo and getnameinfo 9 | =============================================================== 10 | 11 | 12 | .. py:function:: pyuv.dns.getaddrinfo(loop, ... , callback=None) 13 | 14 | Equivalent of `socket.getaddrinfo`. When `callback` is not None, 15 | this function returns a `GAIRequest` object which has a `cancel()` 16 | method that can be called in order to cancel the request. 17 | 18 | Callback signature: ``callback(result, errorno)``. 19 | 20 | When `callback` is None, this function is synchronous. 21 | 22 | .. py:function:: pyuv.dns.getnameinfo(loop, ... , callback=None) 23 | 24 | Equivalent of `socket.getnameinfo`. When `callback` is not None, 25 | this function returns a `GNIRequest` object which has a `cancel()` 26 | method that can be called in order to cancel the request. 27 | 28 | Callback signature: ``callback(result, errorno)``. 29 | 30 | When `callback` is None, this function is synchronous. 31 | 32 | .. note:: 33 | libuv used to bundle c-ares in the past, so the c-ares bindings 34 | are now also `a separated project `_. 35 | The examples directory contains `an example `_ 36 | on how to build a full DNS resolver using the ``Channel`` class provided by pycares 37 | together with pyuv. 38 | 39 | -------------------------------------------------------------------------------- /docs/timer.rst: -------------------------------------------------------------------------------- 1 | .. _timer: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ================================== 8 | :py:class:`Timer` --- Timer handle 9 | ================================== 10 | 11 | 12 | .. py:class:: Timer(loop) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Timer.loop`). 16 | 17 | A ``Timer`` handle will run the supplied callback after the specified amount of seconds. 18 | 19 | .. py:method:: start(callback, timeout, repeat) 20 | 21 | :param callable callback: Function that will be called when the ``Timer`` 22 | handle is run by the event loop. 23 | 24 | :param float timeout: The ``Timer`` will start after the specified amount of time. 25 | 26 | :param float repeat: The ``Timer`` will run again after the specified amount of time. 27 | 28 | Start the ``Timer`` handle. 29 | 30 | Callback signature: ``callback(timer_handle)``. 31 | 32 | .. py:method:: stop 33 | 34 | Stop the ``Timer`` handle. 35 | 36 | .. py:method:: again 37 | 38 | Stop the ``Timer``, and if it is repeating restart it using the repeat value as the timeout. 39 | 40 | .. py:attribute:: repeat 41 | 42 | Get/set the repeat value. Note that if the repeat value is set from a timer callback it does 43 | not immediately take effect. If the timer was non-repeating before, it will have been stopped. 44 | If it was repeating, then the old repeat value will have been used to schedule the next timeout. 45 | 46 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/posix-hrtime.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | #undef NANOSEC 29 | #define NANOSEC ((uint64_t) 1e9) 30 | 31 | uint64_t uv__hrtime(uv_clocktype_t type) { 32 | struct timespec ts; 33 | clock_gettime(CLOCK_MONOTONIC, &ts); 34 | return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); 35 | } 36 | -------------------------------------------------------------------------------- /tests/benchmark-tcp.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | 4 | import sys 5 | sys.path.insert(0, '../') 6 | import signal 7 | import threading 8 | import pyuv 9 | 10 | 11 | RESPONSE = b"HTTP/1.1 200 OK\r\n" \ 12 | "Content-Type: text/plain\r\n" \ 13 | "Content-Length: 12\r\n" \ 14 | "\r\n" \ 15 | "hello world\n" 16 | 17 | 18 | def on_client_shutdown(client, error): 19 | client.close() 20 | clients.remove(client) 21 | 22 | def on_read(client, data, error): 23 | if data is None: 24 | client.close() 25 | clients.remove(client) 26 | return 27 | data = data.strip() 28 | if not data: 29 | return 30 | client.write(RESPONSE) 31 | client.shutdown(on_client_shutdown) 32 | 33 | def on_connection(server, error): 34 | client = pyuv.TCP(server.loop) 35 | server.accept(client) 36 | clients.append(client) 37 | client.start_read(on_read) 38 | 39 | def async_exit(async): 40 | [c.close() for c in clients] 41 | async.close() 42 | signal_h.close() 43 | server.close() 44 | 45 | def signal_cb(handle, signum): 46 | global async 47 | async.send() 48 | 49 | 50 | print("PyUV version %s" % pyuv.__version__) 51 | 52 | loop = pyuv.Loop.default_loop() 53 | 54 | async = pyuv.Async(loop, async_exit) 55 | clients = [] 56 | 57 | server = pyuv.TCP(loop) 58 | server.bind(("0.0.0.0", 1234)) 59 | server.listen(on_connection) 60 | 61 | signal_h = pyuv.Signal(loop) 62 | signal_h.start(signal_cb, signal.SIGINT) 63 | 64 | loop.run() 65 | 66 | print("Stopped!") 67 | 68 | 69 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/sysinfo-loadavg.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | void uv_loadavg(double avg[3]) { 29 | struct sysinfo info; 30 | 31 | if (sysinfo(&info) < 0) return; 32 | 33 | avg[0] = (double) info.loads[0] / 65536.0; 34 | avg[1] = (double) info.loads[1] / 65536.0; 35 | avg[2] = (double) info.loads[2] / 65536.0; 36 | } 37 | -------------------------------------------------------------------------------- /docs/handle.rst: -------------------------------------------------------------------------------- 1 | .. _handle: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ======================================== 8 | :py:class:`Handle` --- Handle base class 9 | ======================================== 10 | 11 | 12 | .. py:class:: Handle 13 | 14 | `Handle` is an internal base class from which all handles inherit in pyuv. It 15 | provides all handles with a number of methods which are common for all. 16 | 17 | .. py:method:: close([callback]) 18 | 19 | :param callable callback: Function that will be called after the handle is closed. 20 | 21 | Close the handle. After a handle has been closed no other 22 | operations can be performed on it, they will raise `HandleClosedError`. 23 | 24 | Callback signature: ``callback(handle)`` 25 | 26 | .. py:attribute:: ref 27 | 28 | Reference/unreference this handle. If running the event loop in default mode (UV_RUN_DEFAULT) 29 | the loop will exit when there are no more ref'd active handles left. Setting ref to True on 30 | a handle will ensure that the loop is maintained alive while the handle is active. Likewise, 31 | if all handles are unref'd, the loop would finish enven if they were all active. 32 | 33 | .. py:attribute:: loop 34 | 35 | *Read only* 36 | 37 | :py:class:`Loop` object where this handle runs. 38 | 39 | .. py:attribute:: active 40 | 41 | *Read only* 42 | 43 | Indicates if this handle is active. 44 | 45 | .. py:attribute:: closed 46 | 47 | *Read only* 48 | 49 | Indicates if this handle is closing or already closed. 50 | 51 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-threadpool.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | /* 23 | * This file is private to libuv. It provides common functionality to both 24 | * Windows and Unix backends. 25 | */ 26 | 27 | #ifndef UV_THREADPOOL_H_ 28 | #define UV_THREADPOOL_H_ 29 | 30 | struct uv__work { 31 | void (*work)(struct uv__work *w); 32 | void (*done)(struct uv__work *w, int status); 33 | struct uv_loop_s* loop; 34 | void* wq[2]; 35 | }; 36 | 37 | #endif /* UV_THREADPOOL_H_ */ 38 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. currentmodule:: pyuv 2 | 3 | 4 | ################################ 5 | Welcome to pyuv's documentation! 6 | ################################ 7 | 8 | Python interface for libuv, a high performance asynchronous networking 9 | and platform abstraction library. 10 | 11 | 12 | .. note:: 13 | pyuv's source code is hosted `on GitHub `_ 14 | 15 | Features: 16 | ######### 17 | 18 | * Non-blocking TCP sockets 19 | * Non-blocking named pipes 20 | * UDP support 21 | * Timers 22 | * Child process spawning 23 | * Asynchronous DNS resolution (getaddrinfo & getnameinfo) 24 | * Asynchronous file system APIs 25 | * Thread pool scheduling 26 | * High resolution time 27 | * System memory information 28 | * System CPUs information 29 | * Network interfaces information 30 | * ANSI escape code controlled TTY 31 | * File system events 32 | * IPC and TCP socket sharing between processes 33 | * Arbitrary file descriptor polling 34 | * Thread synchronization primitives 35 | 36 | .. seealso:: 37 | `libuv's source code `_ 38 | 39 | .. seealso:: 40 | `Official libuv documentation `_ 41 | 42 | 43 | Contents 44 | ######## 45 | 46 | .. toctree:: 47 | :maxdepth: 3 48 | :titlesonly: 49 | 50 | pyuv 51 | refcount 52 | 53 | 54 | Examples 55 | ######## 56 | 57 | .. toctree:: 58 | :maxdepth: 1 59 | 60 | examples 61 | 62 | 63 | ToDo 64 | #### 65 | 66 | .. toctree:: 67 | :maxdepth: 1 68 | 69 | TODO 70 | 71 | 72 | Indices and tables 73 | ################## 74 | 75 | * :ref:`genindex` 76 | * :ref:`modindex` 77 | * :ref:`search` 78 | 79 | -------------------------------------------------------------------------------- /tests/test_loop_handles.py: -------------------------------------------------------------------------------- 1 | 2 | import gc 3 | import unittest 4 | import weakref 5 | 6 | from common import TestCase 7 | import pyuv 8 | 9 | 10 | class HandlesTest(TestCase): 11 | handle_types = ('Check', 'Idle', 'Pipe', 'Prepare', 'TCP', 'Timer', 'UDP') 12 | 13 | def test_handles(self): 14 | timer = pyuv.Timer(self.loop) 15 | self.assertTrue(timer in self.loop.handles) 16 | timer.close() 17 | timer = None 18 | self.loop.run() 19 | self.assertFalse(self.loop.handles) 20 | 21 | def test_handle_lifetime(self): 22 | refs = [] 23 | for type in self.handle_types: 24 | klass = getattr(pyuv, type) 25 | obj = klass(self.loop) 26 | refs.append(weakref.ref(obj)) 27 | del obj 28 | 29 | # There are no more references to the handles at this point. 30 | # Garbage collection should be prevented from freeing them, though. 31 | # Touching each of these without segfault is a best effort check. 32 | # The validity of the weakrefs is implementation dependent :(. 33 | gc.collect() 34 | handles = self.loop.handles 35 | self.assertEqual(len(handles), len(self.handle_types)) 36 | for handle in handles: 37 | self.assertTrue(handle.closed) 38 | del handle 39 | del handles 40 | 41 | # Give the loop a chance to finish closing the handles. 42 | self.loop.run() 43 | 44 | # Ensure the weakref is gone now. 45 | for ref in refs: 46 | self.assertEqual(ref(), None) 47 | 48 | 49 | if __name__ == '__main__': 50 | unittest.main(verbosity=2) 51 | -------------------------------------------------------------------------------- /tests/test_multihandles.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class MultiHandleTest(TestCase): 9 | 10 | def test_multihandle1(self): 11 | self.close_cb_called = 0 12 | self.prepare_cb_called = 0 13 | def close_cb(handle): 14 | self.close_cb_called += 1 15 | def prepare_cb(prepare): 16 | self.prepare_cb_called += 1 17 | prepare.stop() 18 | prepare.close(close_cb) 19 | self.idle_cb_called = 0 20 | def idle_cb(idle): 21 | self.idle_cb_called += 1 22 | idle.stop() 23 | idle.close(close_cb) 24 | self.check_cb_called = 0 25 | def check_cb(check): 26 | self.check_cb_called += 1 27 | check.stop() 28 | check.close(close_cb) 29 | self.timer_cb_called = 0 30 | def timer_cb(timer): 31 | self.timer_cb_called += 1 32 | timer.stop() 33 | timer.close(close_cb) 34 | prepare = pyuv.Prepare(self.loop) 35 | prepare.start(prepare_cb) 36 | idle = pyuv.Idle(self.loop) 37 | idle.start(idle_cb) 38 | check = pyuv.Check(self.loop) 39 | check.start(check_cb) 40 | timer = pyuv.Timer(self.loop) 41 | timer.start(timer_cb, 0.1, 0) 42 | self.loop.run() 43 | self.assertEqual(self.prepare_cb_called, 1) 44 | self.assertEqual(self.idle_cb_called, 1) 45 | self.assertEqual(self.check_cb_called, 1) 46 | self.assertEqual(self.close_cb_called, 4) 47 | 48 | 49 | if __name__ == '__main__': 50 | unittest.main(verbosity=2) 51 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/no-proctitle.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | char** uv_setup_args(int argc, char** argv) { 29 | return argv; 30 | } 31 | 32 | int uv_set_process_title(const char* title) { 33 | return 0; 34 | } 35 | 36 | int uv_get_process_title(char* buffer, size_t size) { 37 | if (buffer == NULL || size == 0) 38 | return -EINVAL; 39 | 40 | buffer[0] = '\0'; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/procfs-exepath.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | int uv_exepath(char* buffer, size_t* size) { 29 | ssize_t n; 30 | 31 | if (buffer == NULL || size == NULL || *size == 0) 32 | return -EINVAL; 33 | 34 | n = *size - 1; 35 | if (n > 0) 36 | n = readlink("/proc/self/exe", buffer, n); 37 | 38 | if (n == -1) 39 | return -errno; 40 | 41 | buffer[n] = '\0'; 42 | *size = n; 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/sysinfo-memory.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | uint64_t uv_get_free_memory(void) { 29 | struct sysinfo info; 30 | 31 | if (sysinfo(&info) == 0) 32 | return (uint64_t) info.freeram * info.mem_unit; 33 | return 0; 34 | } 35 | 36 | uint64_t uv_get_total_memory(void) { 37 | struct sysinfo info; 38 | 39 | if (sysinfo(&info) == 0) 40 | return (uint64_t) info.totalram * info.mem_unit; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /deps/libuv/src/win/snprintf.c: -------------------------------------------------------------------------------- 1 | /* Copyright the libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #if defined(_MSC_VER) && _MSC_VER < 1900 23 | 24 | #include 25 | #include 26 | 27 | /* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer 28 | * on overflow... 29 | */ 30 | int snprintf(char* buf, size_t len, const char* fmt, ...) { 31 | int n; 32 | va_list ap; 33 | va_start(ap, fmt); 34 | 35 | n = _vscprintf(fmt, ap); 36 | vsnprintf_s(buf, len, _TRUNCATE, fmt, ap); 37 | 38 | va_end(ap); 39 | return n; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-posix.h: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_POSIX_H 23 | #define UV_POSIX_H 24 | 25 | #define UV_PLATFORM_LOOP_FIELDS \ 26 | struct pollfd* poll_fds; \ 27 | size_t poll_fds_used; \ 28 | size_t poll_fds_size; \ 29 | unsigned char poll_fds_iterating; \ 30 | 31 | #endif /* UV_POSIX_H */ 32 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-aix.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_AIX_H 23 | #define UV_AIX_H 24 | 25 | #define UV_PLATFORM_LOOP_FIELDS \ 26 | int fs_fd; \ 27 | 28 | #define UV_PLATFORM_FS_EVENT_FIELDS \ 29 | uv__io_t event_watcher; \ 30 | char *dir_filename; \ 31 | 32 | #endif /* UV_AIX_H */ 33 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/no-fsevents.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | 27 | int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { 28 | return -ENOSYS; 29 | } 30 | 31 | int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, 32 | const char* filename, unsigned int flags) { 33 | return -ENOSYS; 34 | } 35 | 36 | int uv_fs_event_stop(uv_fs_event_t* handle) { 37 | return -ENOSYS; 38 | } 39 | 40 | void uv__fs_event_close(uv_fs_event_t* handle) { 41 | UNREACHABLE(); 42 | } 43 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-bsd.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_BSD_H 23 | #define UV_BSD_H 24 | 25 | #define UV_PLATFORM_FS_EVENT_FIELDS \ 26 | uv__io_t event_watcher; \ 27 | 28 | #define UV_IO_PRIVATE_PLATFORM_FIELDS \ 29 | int rcount; \ 30 | int wcount; \ 31 | 32 | #define UV_HAVE_KQUEUE 1 33 | 34 | #endif /* UV_BSD_H */ 35 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-linux.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_LINUX_H 23 | #define UV_LINUX_H 24 | 25 | #define UV_PLATFORM_LOOP_FIELDS \ 26 | uv__io_t inotify_read_watcher; \ 27 | void* inotify_watchers; \ 28 | int inotify_fd; \ 29 | 30 | #define UV_PLATFORM_FS_EVENT_FIELDS \ 31 | void* watchers[2]; \ 32 | int wd; \ 33 | 34 | #endif /* UV_LINUX_H */ 35 | -------------------------------------------------------------------------------- /deps/libuv/src/version.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | 24 | #define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v) 25 | #define UV_STRINGIFY_HELPER(v) #v 26 | 27 | #define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \ 28 | UV_STRINGIFY(UV_VERSION_MINOR) "." \ 29 | UV_STRINGIFY(UV_VERSION_PATCH) 30 | 31 | #if UV_VERSION_IS_RELEASE 32 | # define UV_VERSION_STRING UV_VERSION_STRING_BASE 33 | #else 34 | # define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX 35 | #endif 36 | 37 | 38 | unsigned int uv_version(void) { 39 | return UV_VERSION_HEX; 40 | } 41 | 42 | 43 | const char* uv_version_string(void) { 44 | return UV_VERSION_STRING; 45 | } 46 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/cygwin.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | int uv_uptime(double* uptime) { 29 | struct sysinfo info; 30 | 31 | if (sysinfo(&info) < 0) 32 | return -errno; 33 | 34 | *uptime = info.uptime; 35 | return 0; 36 | } 37 | 38 | int uv_resident_set_memory(size_t* rss) { 39 | /* FIXME: read /proc/meminfo? */ 40 | *rss = 0; 41 | return UV_ENOSYS; 42 | } 43 | 44 | int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 45 | /* FIXME: read /proc/stat? */ 46 | *cpu_infos = NULL; 47 | *count = 0; 48 | return UV_ENOSYS; 49 | } 50 | 51 | void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { 52 | (void)cpu_infos; 53 | (void)count; 54 | } 55 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import codecs 4 | import re 5 | 6 | try: 7 | from setuptools import setup, Extension 8 | except ImportError: 9 | from distutils.core import setup, Extension 10 | from setup_libuv import libuv_build_ext 11 | 12 | 13 | def get_version(): 14 | return re.search(r"""__version__\s+=\s+(?P['"])(?P.+?)(?P=quote)""", open('pyuv/_version.py').read()).group('version') 15 | 16 | 17 | setup(name = 'pyuv', 18 | version = get_version(), 19 | author = 'Saúl Ibarra Corretgé', 20 | author_email = 'saghul@gmail.com', 21 | url = 'http://github.com/saghul/pyuv', 22 | description = 'Python interface for libuv', 23 | long_description = codecs.open('README.rst', encoding='utf-8').read(), 24 | platforms = ['POSIX', 'Microsoft Windows'], 25 | classifiers = [ 26 | 'Development Status :: 5 - Production/Stable', 27 | 'Intended Audience :: Developers', 28 | 'License :: OSI Approved :: MIT License', 29 | 'Operating System :: POSIX', 30 | 'Operating System :: Microsoft :: Windows', 31 | 'Programming Language :: Python', 32 | 'Programming Language :: Python :: 2', 33 | 'Programming Language :: Python :: 2.7', 34 | 'Programming Language :: Python :: 3', 35 | 'Programming Language :: Python :: 3.3', 36 | 'Programming Language :: Python :: 3.4', 37 | 'Programming Language :: Python :: 3.5', 38 | 'Programming Language :: Python :: 3.6', 39 | 'Programming Language :: Python :: Implementation :: CPython', 40 | 'Programming Language :: Python :: Implementation :: PyPy', 41 | ], 42 | cmdclass = {'build_ext': libuv_build_ext}, 43 | packages = ['pyuv'], 44 | ext_modules = [Extension('pyuv._cpyuv', 45 | sources = ['src/pyuv.c'], 46 | )] 47 | ) 48 | 49 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-version.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_VERSION_H 23 | #define UV_VERSION_H 24 | 25 | /* 26 | * Versions with the same major number are ABI stable. API is allowed to 27 | * evolve between minor releases, but only in a backwards compatible way. 28 | * Make sure you update the -soname directives in configure.ac 29 | * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but 30 | * not UV_VERSION_PATCH.) 31 | */ 32 | 33 | #define UV_VERSION_MAJOR 1 34 | #define UV_VERSION_MINOR 13 35 | #define UV_VERSION_PATCH 2 36 | #define UV_VERSION_IS_RELEASE 0 37 | #define UV_VERSION_SUFFIX "dev" 38 | 39 | #define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \ 40 | (UV_VERSION_MINOR << 8) | \ 41 | (UV_VERSION_PATCH)) 42 | 43 | #endif /* UV_VERSION_H */ 44 | -------------------------------------------------------------------------------- /deps/libuv/include/android-ifaddrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1999 3 | * Berkeley Software Design, Inc. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND 12 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14 | * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE 15 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 17 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 20 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 21 | * SUCH DAMAGE. 22 | * 23 | * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp 24 | */ 25 | 26 | #ifndef _IFADDRS_H_ 27 | #define _IFADDRS_H_ 28 | 29 | struct ifaddrs { 30 | struct ifaddrs *ifa_next; 31 | char *ifa_name; 32 | unsigned int ifa_flags; 33 | struct sockaddr *ifa_addr; 34 | struct sockaddr *ifa_netmask; 35 | struct sockaddr *ifa_dstaddr; 36 | void *ifa_data; 37 | }; 38 | 39 | /* 40 | * This may have been defined in . Note that if is 41 | * to be included it must be included before this header file. 42 | */ 43 | #ifndef ifa_broadaddr 44 | #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 45 | #endif 46 | 47 | #include 48 | 49 | __BEGIN_DECLS 50 | extern int getifaddrs(struct ifaddrs **ifap); 51 | extern void freeifaddrs(struct ifaddrs *ifa); 52 | __END_DECLS 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tasks.py: -------------------------------------------------------------------------------- 1 | 2 | import invoke 3 | 4 | import datetime 5 | import re 6 | import sys 7 | 8 | 9 | cmd = 'git log $(git describe --tags --abbrev=0)..HEAD --format=" - %s" | tac' 10 | changelog_template = 'Version %s\n=============\n%s\n' 11 | tag_template = '%s - pyuv version %s\n\n%s\n' 12 | 13 | 14 | def get_version(): 15 | return re.search(r"""__version__\s+=\s+(?P['"])(?P.+?)(?P=quote)""", open('pyuv/_version.py').read()).group('version') 16 | 17 | def check_repo(): 18 | r = invoke.run('git diff-files --quiet', hide=True, warn=True) 19 | if r.failed: 20 | print 'The repository is not clean' 21 | sys.exit(1) 22 | 23 | @invoke.task 24 | def changelog(): 25 | check_repo() 26 | version = get_version() 27 | with open('ChangeLog', 'r+') as f: 28 | content = f.read() 29 | if content.startswith('Version %s' % version): 30 | print 'ChangeLog was already generated' 31 | sys.exit(1) 32 | changelog = invoke.run(cmd, hide=True).stdout 33 | f.seek(0) 34 | f.write(changelog_template % (version, changelog)) 35 | f.write(content) 36 | invoke.run('git commit -a -m "core: updated changelog"') 37 | print changelog_template % (version, changelog) 38 | print 'The above ChangeLog was written, please adjust and amend as necessary' 39 | 40 | @invoke.task 41 | def release(): 42 | check_repo() 43 | version = get_version() 44 | with open('ChangeLog', 'r') as f: 45 | content = f.read() 46 | changelog = content[:content.find('\n\n')] 47 | dt = datetime.datetime.utcnow().replace(microsecond=0) 48 | tag = tag_template % (dt, version, changelog) 49 | invoke.run('git tag -s -a pyuv-{0} -m "{1}"'.format(version, tag)) 50 | 51 | @invoke.task 52 | def push(): 53 | check_repo() 54 | invoke.run("git push") 55 | invoke.run("git push --tags") 56 | 57 | @invoke.task 58 | def upload(): 59 | check_repo() 60 | version = get_version() 61 | invoke.run("python setup.py sdist") 62 | invoke.run("twine upload -r pypi dist/pyuv-{0}*".format(version)) 63 | 64 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-sunos.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_SUNOS_H 23 | #define UV_SUNOS_H 24 | 25 | #include 26 | #include 27 | 28 | /* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c, 29 | * add the fs_event fields even when this version of SunOS doesn't support 30 | * file watching. 31 | */ 32 | #define UV_PLATFORM_LOOP_FIELDS \ 33 | uv__io_t fs_event_watcher; \ 34 | int fs_fd; \ 35 | 36 | #if defined(PORT_SOURCE_FILE) 37 | 38 | # define UV_PLATFORM_FS_EVENT_FIELDS \ 39 | file_obj_t fo; \ 40 | int fd; \ 41 | 42 | #endif /* defined(PORT_SOURCE_FILE) */ 43 | 44 | #endif /* UV_SUNOS_H */ 45 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/spinlock.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Ben Noordhuis 2 | * 3 | * Permission to use, copy, modify, and/or distribute this software for any 4 | * purpose with or without fee is hereby granted, provided that the above 5 | * copyright notice and this permission notice appear in all copies. 6 | * 7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | */ 15 | 16 | #ifndef UV_SPINLOCK_H_ 17 | #define UV_SPINLOCK_H_ 18 | 19 | #include "internal.h" /* ACCESS_ONCE, UV_UNUSED */ 20 | #include "atomic-ops.h" 21 | 22 | #define UV_SPINLOCK_INITIALIZER { 0 } 23 | 24 | typedef struct { 25 | int lock; 26 | } uv_spinlock_t; 27 | 28 | UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)); 29 | UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)); 30 | UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)); 31 | UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)); 32 | 33 | UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)) { 34 | ACCESS_ONCE(int, spinlock->lock) = 0; 35 | } 36 | 37 | UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)) { 38 | while (!uv_spinlock_trylock(spinlock)) cpu_relax(); 39 | } 40 | 41 | UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)) { 42 | ACCESS_ONCE(int, spinlock->lock) = 0; 43 | } 44 | 45 | UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)) { 46 | /* TODO(bnoordhuis) Maybe change to a ticket lock to guarantee fair queueing. 47 | * Not really critical until we have locks that are (frequently) contended 48 | * for by several threads. 49 | */ 50 | return 0 == cmpxchgi(&spinlock->lock, 0, 1); 51 | } 52 | 53 | #endif /* UV_SPINLOCK_H_ */ 54 | -------------------------------------------------------------------------------- /tests/test_signal.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import signal 4 | import time 5 | import threading 6 | import unittest 7 | 8 | from common import platform_skip, TestCase 9 | import pyuv 10 | 11 | 12 | @platform_skip(["win32"]) 13 | class SignalTest(TestCase): 14 | 15 | def signal_cb(self, handle, signum): 16 | self.assertEqual(signum, signal.SIGUSR1) 17 | self.signal_cb_called += 1 18 | self.async_.send() 19 | 20 | def async_cb(self, async_): 21 | self.async_cb_called += 1 22 | self.async_.close() 23 | self.signal_h.close() 24 | 25 | def test_signal1(self): 26 | self.async_cb_called = 0 27 | self.signal_cb_called = 0 28 | self.async_ = pyuv.Async(self.loop, self.async_cb) 29 | self.signal_h = pyuv.Signal(self.loop) 30 | self.signal_h.start(self.signal_cb, signal.SIGUSR1) 31 | thread = threading.Thread(target=self.loop.run) 32 | thread.start() 33 | os.kill(os.getpid(), signal.SIGUSR1) 34 | thread.join() 35 | self.assertEqual(self.async_cb_called, 1) 36 | self.assertEqual(self.signal_cb_called, 1) 37 | 38 | 39 | @platform_skip(["win32"]) 40 | class MultiLoopSignalTest(unittest.TestCase): 41 | 42 | def setUp(self): 43 | self.lock = threading.Lock() 44 | self.signal_cb_called = 0 45 | 46 | def signal_cb(self, handle, signum): 47 | self.assertEqual(signum, signal.SIGUSR1) 48 | with self.lock: 49 | self.signal_cb_called += 1 50 | handle.close() 51 | 52 | def run_loop(self): 53 | loop = pyuv.Loop() 54 | signal_h = pyuv.Signal(loop) 55 | signal_h.start(self.signal_cb, signal.SIGUSR1) 56 | loop.run() 57 | 58 | def test_multi_loop_signals(self): 59 | threads = [threading.Thread(target=self.run_loop) for x in range(25)] 60 | [t.start() for t in threads] 61 | # Wait until threads have started 62 | time.sleep(1) 63 | os.kill(os.getpid(), signal.SIGUSR1) 64 | [t.join() for t in threads] 65 | self.assertEqual(self.signal_cb_called, 25) 66 | 67 | 68 | if __name__ == '__main__': 69 | unittest.main(verbosity=2) 70 | -------------------------------------------------------------------------------- /deps/libuv/src/win/stream-inl.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_WIN_STREAM_INL_H_ 23 | #define UV_WIN_STREAM_INL_H_ 24 | 25 | #include 26 | 27 | #include "uv.h" 28 | #include "internal.h" 29 | #include "handle-inl.h" 30 | #include "req-inl.h" 31 | 32 | 33 | INLINE static void uv_stream_init(uv_loop_t* loop, 34 | uv_stream_t* handle, 35 | uv_handle_type type) { 36 | uv__handle_init(loop, (uv_handle_t*) handle, type); 37 | handle->write_queue_size = 0; 38 | handle->activecnt = 0; 39 | } 40 | 41 | 42 | INLINE static void uv_connection_init(uv_stream_t* handle) { 43 | handle->flags |= UV_HANDLE_CONNECTION; 44 | handle->stream.conn.write_reqs_pending = 0; 45 | 46 | UV_REQ_INIT(&handle->read_req, UV_READ); 47 | handle->read_req.event_handle = NULL; 48 | handle->read_req.wait_handle = INVALID_HANDLE_VALUE; 49 | handle->read_req.data = handle; 50 | 51 | handle->stream.conn.shutdown_req = NULL; 52 | } 53 | 54 | 55 | #endif /* UV_WIN_STREAM_INL_H_ */ 56 | -------------------------------------------------------------------------------- /deps/libuv/include/pthread-barrier.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016, Kari Tristan Helgason 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _UV_PTHREAD_BARRIER_ 18 | #define _UV_PTHREAD_BARRIER_ 19 | #include 20 | #include 21 | #if !defined(__MVS__) 22 | #include /* sem_t */ 23 | #endif 24 | 25 | #define PTHREAD_BARRIER_SERIAL_THREAD 0x12345 26 | 27 | /* 28 | * To maintain ABI compatibility with 29 | * libuv v1.x struct is padded according 30 | * to target platform 31 | */ 32 | #if defined(__ANDROID__) 33 | # define UV_BARRIER_STRUCT_PADDING \ 34 | sizeof(pthread_mutex_t) + \ 35 | sizeof(pthread_cond_t) + \ 36 | sizeof(unsigned int) - \ 37 | sizeof(void *) 38 | #elif defined(__APPLE__) 39 | # define UV_BARRIER_STRUCT_PADDING \ 40 | sizeof(pthread_mutex_t) + \ 41 | 2 * sizeof(sem_t) + \ 42 | 2 * sizeof(unsigned int) - \ 43 | sizeof(void *) 44 | #else 45 | # define UV_BARRIER_STRUCT_PADDING 0 46 | #endif 47 | 48 | typedef struct { 49 | pthread_mutex_t mutex; 50 | pthread_cond_t cond; 51 | unsigned threshold; 52 | unsigned in; 53 | unsigned out; 54 | } _uv_barrier; 55 | 56 | typedef struct { 57 | _uv_barrier* b; 58 | char _pad[UV_BARRIER_STRUCT_PADDING]; 59 | } pthread_barrier_t; 60 | 61 | int pthread_barrier_init(pthread_barrier_t* barrier, 62 | const void* barrier_attr, 63 | unsigned count); 64 | 65 | int pthread_barrier_wait(pthread_barrier_t* barrier); 66 | int pthread_barrier_destroy(pthread_barrier_t *barrier); 67 | 68 | #endif /* _UV_PTHREAD_BARRIER_ */ 69 | -------------------------------------------------------------------------------- /tests/test_async.py: -------------------------------------------------------------------------------- 1 | 2 | import threading 3 | import time 4 | import unittest 5 | 6 | from common import TestCase 7 | import pyuv 8 | 9 | 10 | class AsyncTest(TestCase): 11 | 12 | def test_async1(self): 13 | self.async_cb_called = 0 14 | self.prepare_cb_called = 0 15 | def async_cb(async_): 16 | with self.lock: 17 | self.async_cb_called += 1 18 | n = self.async_cb_called 19 | if n == 3: 20 | self.async_.close() 21 | self.prepare.close() 22 | def prepare_cb(prepare): 23 | if self.prepare_cb_called: 24 | return 25 | self.prepare_cb_called += 1 26 | self.thread = threading.Thread(target=thread_cb) 27 | self.thread.start() 28 | def thread_cb(): 29 | while True: 30 | with self.lock: 31 | n = self.async_cb_called 32 | if n == 3: 33 | break 34 | self.async_.send() 35 | self.async_ = pyuv.Async(self.loop, async_cb) 36 | self.prepare = pyuv.Prepare(self.loop) 37 | self.prepare.start(prepare_cb) 38 | self.lock = threading.Lock() 39 | self.loop.run() 40 | self.assertEqual(self.async_cb_called, 3) 41 | self.assertEqual(self.prepare_cb_called, 1) 42 | 43 | def test_async2(self): 44 | self.prepare_cb_called = 0 45 | self.check_cb_called = 0 46 | def prepare_cb(prepare): 47 | self.prepare_cb_called += 1 48 | self.thread = threading.Thread(target=thread_cb) 49 | self.thread.start() 50 | def check_cb(check): 51 | self.check_cb_called += 1 52 | self.loop.stop() 53 | def thread_cb(): 54 | time.sleep(0.01) 55 | self.async_.send() 56 | self.async_ = pyuv.Async(self.loop) 57 | self.prepare = pyuv.Prepare(self.loop) 58 | self.prepare.start(prepare_cb) 59 | self.check = pyuv.Check(self.loop) 60 | self.check.start(check_cb) 61 | self.loop.run() 62 | self.assertEqual(self.prepare_cb_called, 1) 63 | self.assertEqual(self.check_cb_called, 1) 64 | 65 | 66 | if __name__ == '__main__': 67 | unittest.main(verbosity=2) 68 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/pthread-fixes.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Sony Mobile Communications AB 2 | * Copyright (c) 2012, Google Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following disclaimer 13 | in the documentation and/or other materials provided with the 14 | distribution. 15 | * Neither the name of Google Inc. nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* Android versions < 4.1 have a broken pthread_sigmask. */ 33 | #include 34 | #include 35 | #include 36 | 37 | int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) { 38 | static int workaround; 39 | int err; 40 | 41 | if (workaround) { 42 | return sigprocmask(how, set, oset); 43 | } else { 44 | err = pthread_sigmask(how, set, oset); 45 | if (err) { 46 | if (err == EINVAL && sigprocmask(how, set, oset) == 0) { 47 | workaround = 1; 48 | return 0; 49 | } else { 50 | return -1; 51 | } 52 | } 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /src/errno.c: -------------------------------------------------------------------------------- 1 | 2 | /* Borrowed code from Python (Modules/errnomodule.c) */ 3 | 4 | static void 5 | inscode(PyObject *module_dict, PyObject *other_dict, const char *name, int code) 6 | { 7 | PyObject *error_name = Py_BuildValue("s", name); 8 | PyObject *error_code = PyInt_FromLong((long) code); 9 | 10 | /* Don't bother checking for errors; they'll be caught at the end 11 | * of the module initialization function by the caller of 12 | * init_errno(). 13 | */ 14 | if (error_name && error_code) { 15 | PyDict_SetItem(module_dict, error_name, error_code); 16 | PyDict_SetItem(other_dict, error_code, error_name); 17 | } 18 | Py_XDECREF(error_name); 19 | Py_XDECREF(error_code); 20 | } 21 | 22 | 23 | static PyObject * 24 | Errno_func_strerror(PyObject *obj, PyObject *args) 25 | { 26 | int errorno; 27 | UNUSED_ARG(obj); 28 | 29 | if (!PyArg_ParseTuple(args, "i:strerror", &errorno)) { 30 | return NULL; 31 | } 32 | return Py_BuildValue("s", uv_strerror(errorno)); 33 | } 34 | 35 | 36 | static PyMethodDef 37 | Errno_methods[] = { 38 | { "strerror", (PyCFunction)Errno_func_strerror, METH_VARARGS, "Get string representation of an error code." }, 39 | { NULL } 40 | }; 41 | 42 | 43 | #ifdef PYUV_PYTHON3 44 | static PyModuleDef pyuv_errno_module = { 45 | PyModuleDef_HEAD_INIT, 46 | "pyuv._cpyuv.errno", /*m_name*/ 47 | NULL, /*m_doc*/ 48 | -1, /*m_size*/ 49 | Errno_methods, /*m_methods*/ 50 | }; 51 | #endif 52 | 53 | PyObject * 54 | init_errno(void) 55 | { 56 | PyObject *module; 57 | PyObject *module_dict; 58 | PyObject *errorcode_dict; 59 | #ifdef PYUV_PYTHON3 60 | module = PyModule_Create(&pyuv_errno_module); 61 | #else 62 | module = Py_InitModule("pyuv._cpyuv.errno", Errno_methods); 63 | #endif 64 | if (module == NULL) { 65 | return NULL; 66 | } 67 | 68 | module_dict = PyModule_GetDict(module); 69 | errorcode_dict = PyDict_New(); 70 | if (!module_dict || !errorcode_dict || PyDict_SetItemString(module_dict, "errorcode", errorcode_dict) < 0) { 71 | return NULL; 72 | } 73 | 74 | #define XX(name, s) inscode(module_dict, errorcode_dict, PYUV_STRINGIFY(UV_##name), UV_##name); 75 | UV_ERRNO_MAP(XX) 76 | #undef XX 77 | 78 | Py_DECREF(errorcode_dict); 79 | 80 | return module; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /tests/test_embed.py: -------------------------------------------------------------------------------- 1 | 2 | import errno 3 | import select 4 | import unittest 5 | 6 | from threading import Thread 7 | 8 | import common; common 9 | import pyuv 10 | 11 | try: 12 | poller = select.epoll 13 | poller_type = 'epoll' 14 | except AttributeError: 15 | try: 16 | poller = select.kqueue 17 | poller_type = 'kqueue' 18 | except AttributeError: 19 | poller = None 20 | 21 | 22 | class EmbedTest(unittest.TestCase): 23 | 24 | def embed_cb(self, handle): 25 | self.loop.run(pyuv.UV_RUN_ONCE) 26 | self.sem.post() 27 | 28 | def timer_cb(self, handle): 29 | self.embed_timer_called += 1 30 | self.embed_closed = True 31 | self.embed_async.close() 32 | handle.close() 33 | 34 | def poll(self, poll_obj, timeout): 35 | if poller_type == 'kqueue': 36 | poll_obj.control(None, 0, timeout) 37 | elif poller_type == 'epoll': 38 | poll_obj.poll(timeout) 39 | else: 40 | self.fail('Bogus poller type') 41 | 42 | def embed_runner(self): 43 | fd = self.loop.fileno() 44 | poll = poller.fromfd(fd) 45 | while not self.embed_closed: 46 | timeout = self.loop.get_timeout() 47 | while True: 48 | try: 49 | self.poll(poll, timeout) 50 | except OSError as e: 51 | if e.args[0] == errno.EINTR: 52 | continue 53 | break 54 | self.embed_async.send() 55 | self.sem.wait() 56 | 57 | def test_embed(self): 58 | if poller is None: 59 | self.skipTest("test disabled if no suitable poller method is found") 60 | return 61 | self.embed_timer_called = 0 62 | self.embed_closed = False 63 | self.external = pyuv.Loop() 64 | self.embed_async = pyuv.Async(self.external, self.embed_cb) 65 | 66 | self.loop = pyuv.Loop() 67 | timer = pyuv.Timer(self.loop) 68 | timer.start(self.timer_cb, 0.25, 0) 69 | 70 | self.sem = pyuv.thread.Semaphore(0) 71 | t = Thread(target=self.embed_runner) 72 | t.start() 73 | self.external.run() 74 | t.join() 75 | external = None 76 | 77 | self.assertEqual(self.embed_timer_called, 1) 78 | 79 | 80 | if __name__ == '__main__': 81 | unittest.main(verbosity=2) 82 | 83 | -------------------------------------------------------------------------------- /tests/test_loop.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | from common import TestCase 5 | import pyuv 6 | 7 | 8 | class LoopRunTest(TestCase): 9 | 10 | def test_run_once(self): 11 | self.cb_called = 0 12 | def prepare_cb(handle): 13 | handle.close() 14 | self.cb_called += 1 15 | for i in range(500): 16 | prepare = pyuv.Prepare(self.loop) 17 | prepare.start(prepare_cb) 18 | self.loop.run(pyuv.UV_RUN_ONCE) 19 | self.assertEqual(self.cb_called, 500) 20 | 21 | def test_run_nowait(self): 22 | self.cb_called = 0 23 | def timer_cb(handle): 24 | handle.close() 25 | self.cb_called = 1 26 | timer = pyuv.Timer(self.loop) 27 | timer.start(timer_cb, 10, 10) 28 | self.loop.run(pyuv.UV_RUN_NOWAIT) 29 | self.assertEqual(self.cb_called, 0) 30 | 31 | def test_stop(self): 32 | self.num_ticks = 10 33 | self.prepare_called = 0 34 | self.timer_called = 0 35 | def timer_cb(handle): 36 | self.timer_called += 1 37 | if self.timer_called == 1: 38 | self.loop.stop() 39 | elif self.timer_called == self.num_ticks: 40 | handle.close() 41 | def prepare_cb(handle): 42 | self.prepare_called += 1 43 | if self.prepare_called == self.num_ticks: 44 | handle.close() 45 | timer = pyuv.Timer(self.loop) 46 | timer.start(timer_cb, 0.1, 0.1) 47 | prepare = pyuv.Prepare(self.loop) 48 | prepare.start(prepare_cb) 49 | self.loop.run(pyuv.UV_RUN_DEFAULT) 50 | self.assertEqual(self.timer_called, 1) 51 | self.assertTrue(self.prepare_called >= 2) 52 | self.loop.run(pyuv.UV_RUN_NOWAIT) 53 | self.assertTrue(self.prepare_called >= 3) 54 | self.loop.run(pyuv.UV_RUN_DEFAULT) 55 | self.assertEqual(self.timer_called, 10) 56 | self.assertEqual(self.prepare_called, 10) 57 | 58 | 59 | class LoopAliveTest(TestCase): 60 | 61 | def test_loop_alive(self): 62 | def prepare_cb(handle): 63 | self.assertEqual(self.loop.alive, 1) 64 | handle.close() 65 | prepare = pyuv.Prepare(self.loop) 66 | prepare.start(prepare_cb) 67 | self.loop.run(pyuv.UV_RUN_ONCE) 68 | 69 | 70 | if __name__ == '__main__': 71 | unittest.main(verbosity=2) 72 | -------------------------------------------------------------------------------- /deps/libuv/src/win/atomicops-inl.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_WIN_ATOMICOPS_INL_H_ 23 | #define UV_WIN_ATOMICOPS_INL_H_ 24 | 25 | #include "uv.h" 26 | #include "internal.h" 27 | 28 | 29 | /* Atomic set operation on char */ 30 | #ifdef _MSC_VER /* MSVC */ 31 | 32 | /* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */ 33 | /* efficient than InterlockedExchange, but InterlockedExchange8 does not */ 34 | /* exist, and interlocked operations on larger targets might require the */ 35 | /* target to be aligned. */ 36 | #pragma intrinsic(_InterlockedOr8) 37 | 38 | static char INLINE uv__atomic_exchange_set(char volatile* target) { 39 | return _InterlockedOr8(target, 1); 40 | } 41 | 42 | #else /* GCC */ 43 | 44 | /* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ 45 | static inline char uv__atomic_exchange_set(char volatile* target) { 46 | const char one = 1; 47 | char old_value; 48 | __asm__ __volatile__ ("lock xchgb %0, %1\n\t" 49 | : "=r"(old_value), "=m"(*target) 50 | : "0"(one), "m"(*target) 51 | : "memory"); 52 | return old_value; 53 | } 54 | 55 | #endif 56 | 57 | #endif /* UV_WIN_ATOMICOPS_INL_H_ */ 58 | -------------------------------------------------------------------------------- /tests/common.py: -------------------------------------------------------------------------------- 1 | 2 | import io 3 | import os 4 | import sys 5 | import unittest 6 | 7 | if 'PYUV_INSIDE_TOX' not in os.environ: 8 | sys.path.insert(0, '../') 9 | 10 | import pyuv 11 | 12 | 13 | if sys.version_info >= (3,): 14 | linesep = os.linesep.encode() 15 | StdBufferIO = io.StringIO 16 | 17 | def reraise(typ, value, tb): 18 | if value.__traceback__ is not tb: 19 | raise value.with_traceback(tb) 20 | raise value 21 | else: 22 | linesep = os.linesep 23 | 24 | class StdBufferIO(io.BytesIO): 25 | def write(self, data): 26 | return super(StdBufferIO, self).write(data.encode('utf-8')) 27 | 28 | exec("""\ 29 | def reraise(typ, value, tb): 30 | raise typ, value, tb 31 | """) 32 | 33 | 34 | platform = 'linux' if sys.platform.startswith('linux') else sys.platform 35 | 36 | # decorator for class 37 | def platform_skip(platform_list): 38 | def _noop(obj): 39 | return obj 40 | if platform in platform_list: 41 | return unittest.skip("Test disabled in the current platform") 42 | return _noop 43 | 44 | # decorator for class 45 | def platform_only(platform_list): 46 | def _noop(obj): 47 | return obj 48 | if platform not in platform_list: 49 | return unittest.skip("Test disabled in the current platform") 50 | return _noop 51 | 52 | 53 | class TestLoop(pyuv.Loop): 54 | 55 | def __init__(self): 56 | super(TestLoop, self).__init__() 57 | self.excepthook = self._handle_exception_in_callback 58 | 59 | def run(self, *args, **kwargs): 60 | self._callback_exc_info = None 61 | super(TestLoop, self).run(*args, **kwargs) 62 | self._reraise() 63 | 64 | def _handle_exception_in_callback(self, typ, value, tb): 65 | if self._callback_exc_info is None: 66 | self._callback_exc_info = typ, value, tb 67 | self.stop() 68 | 69 | def _reraise(self): 70 | if self._callback_exc_info is not None: 71 | typ, value, tb = self._callback_exc_info 72 | self._callback_exc_info = None 73 | reraise(typ, value, tb) 74 | 75 | 76 | class TestCase(unittest.TestCase): 77 | 78 | def setUp(self): 79 | self.loop = TestLoop() 80 | 81 | def tearDown(self): 82 | for handle in self.loop.handles: 83 | try: 84 | handle.close() 85 | except: 86 | pass 87 | self.loop.run() 88 | -------------------------------------------------------------------------------- /tests/test_dns.py: -------------------------------------------------------------------------------- 1 | 2 | import socket 3 | import unittest 4 | 5 | from common import TestCase 6 | import pyuv 7 | 8 | 9 | class DnsTest(TestCase): 10 | 11 | def test_getaddrinfo(self): 12 | def getaddrinfo_cb(result, errorno): 13 | self.assertEqual(errorno, None) 14 | pyuv.dns.getaddrinfo(self.loop, 'localhost', 80, socket.AF_INET, callback=getaddrinfo_cb) 15 | self.loop.run() 16 | 17 | def test_getaddrinfo_sync(self): 18 | res = pyuv.dns.getaddrinfo(self.loop, 'localhost', 80, socket.AF_INET) 19 | self.loop.run() 20 | self.assertNotEqual(res, None) 21 | 22 | def test_getaddrinfo_sync_fail(self): 23 | self.assertRaises(pyuv.error.UVError, pyuv.dns.getaddrinfo, self.loop, 'lala.lala.lala', 80, socket.AF_INET) 24 | self.loop.run() 25 | 26 | def test_getaddrinfo_none(self): 27 | def getaddrinfo_cb(result, errorno): 28 | self.assertEqual(errorno, None) 29 | self.assertEqual(result[0][4][1], 0) 30 | pyuv.dns.getaddrinfo(self.loop, 'localhost', None, socket.AF_INET, callback=getaddrinfo_cb) 31 | self.loop.run() 32 | 33 | def test_getaddrinfo_service(self): 34 | def getaddrinfo_cb(result, errorno): 35 | self.assertEqual(errorno, None) 36 | self.assertEqual(result[0][4][1], 80) 37 | pyuv.dns.getaddrinfo(self.loop, 'localhost', 'http', socket.AF_INET, callback=getaddrinfo_cb) 38 | self.loop.run() 39 | 40 | def test_getaddrinfo_service_bytes(self): 41 | def getaddrinfo_cb(result, errorno): 42 | self.assertEqual(errorno, None) 43 | self.assertEqual(result[0][4][1], 80) 44 | pyuv.dns.getaddrinfo(self.loop, b'localhost', b'http', socket.AF_INET, callback=getaddrinfo_cb) 45 | self.loop.run() 46 | 47 | def test_getnameinfo_ipv4(self): 48 | def cb(result, errorno): 49 | self.assertEqual(errorno, None) 50 | pyuv.dns.getnameinfo(self.loop, ('127.0.0.1', 80), callback=cb) 51 | self.loop.run() 52 | 53 | def test_getnameinfo_ipv6(self): 54 | def cb(result, errorno): 55 | self.assertEqual(errorno, None) 56 | pyuv.dns.getnameinfo(self.loop, ('::1', 80), callback=cb) 57 | self.loop.run() 58 | 59 | def test_getnameinfo_sync(self): 60 | result = pyuv.dns.getnameinfo(self.loop, ('127.0.0.1', 80)) 61 | self.loop.run() 62 | self.assertNotEqual(result, None) 63 | 64 | 65 | if __name__ == '__main__': 66 | unittest.main(verbosity=2) 67 | -------------------------------------------------------------------------------- /tests/test_basetype.py: -------------------------------------------------------------------------------- 1 | 2 | import socket 3 | import unittest 4 | 5 | from common import TestCase 6 | import pyuv 7 | 8 | 9 | class TestBasetype(TestCase): 10 | 11 | def _inheritance_test(self, base, *args, **kwargs): 12 | derived = type(base.__name__, (base,), {}) 13 | assert derived is not base 14 | assert issubclass(derived, base) 15 | instance = derived(*args, **kwargs) 16 | assert isinstance(instance, base) 17 | assert isinstance(instance, derived) 18 | 19 | def test_inherit_loop(self): 20 | self._inheritance_test(pyuv.Loop) 21 | 22 | def test_inherit_timer(self): 23 | self._inheritance_test(pyuv.Timer, self.loop) 24 | 25 | def test_inherit_tcp(self): 26 | self._inheritance_test(pyuv.TCP, self.loop) 27 | 28 | def test_inherit_udp(self): 29 | self._inheritance_test(pyuv.UDP, self.loop) 30 | 31 | def test_inherit_poll(self): 32 | sock = socket.socket() 33 | self._inheritance_test(pyuv.Poll, self.loop, sock.fileno()) 34 | sock.close() 35 | 36 | def test_inherit_pipe(self): 37 | self._inheritance_test(pyuv.Pipe, self.loop) 38 | 39 | def test_inherit_process(self): 40 | self._inheritance_test(pyuv.Process, self.loop) 41 | 42 | def test_inherit_async(self): 43 | callback = lambda handle: handle 44 | self._inheritance_test(pyuv.Async, self.loop, callback) 45 | 46 | def test_inherit_prepare(self): 47 | self._inheritance_test(pyuv.Prepare, self.loop) 48 | 49 | def test_inherit_idle(self): 50 | self._inheritance_test(pyuv.Idle, self.loop) 51 | 52 | def test_inherit_check(self): 53 | self._inheritance_test(pyuv.Check, self.loop) 54 | 55 | def test_inherit_signal(self): 56 | self._inheritance_test(pyuv.Signal, self.loop) 57 | 58 | def test_inherit_fs_fspoll(self): 59 | self._inheritance_test(pyuv.fs.FSPoll, self.loop) 60 | 61 | def test_inherit_thread_barrier(self): 62 | self._inheritance_test(pyuv.thread.Barrier, 1) 63 | 64 | def test_inherit_thread_condition(self): 65 | self._inheritance_test(pyuv.thread.Condition) 66 | 67 | def test_inherit_thread_mutex(self): 68 | self._inheritance_test(pyuv.thread.Mutex) 69 | 70 | def test_inherit_thread_rwlock(self): 71 | self._inheritance_test(pyuv.thread.RWLock) 72 | 73 | def test_inherit_thread_semaphore(self): 74 | self._inheritance_test(pyuv.thread.Semaphore, 1) 75 | 76 | 77 | if __name__ == '__main__': 78 | unittest.main(verbosity=2) 79 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/dl.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static int uv__dlerror(uv_lib_t* lib); 31 | 32 | 33 | int uv_dlopen(const char* filename, uv_lib_t* lib) { 34 | dlerror(); /* Reset error status. */ 35 | lib->errmsg = NULL; 36 | lib->handle = dlopen(filename, RTLD_LAZY); 37 | return lib->handle ? 0 : uv__dlerror(lib); 38 | } 39 | 40 | 41 | void uv_dlclose(uv_lib_t* lib) { 42 | uv__free(lib->errmsg); 43 | lib->errmsg = NULL; 44 | 45 | if (lib->handle) { 46 | /* Ignore errors. No good way to signal them without leaking memory. */ 47 | dlclose(lib->handle); 48 | lib->handle = NULL; 49 | } 50 | } 51 | 52 | 53 | int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { 54 | dlerror(); /* Reset error status. */ 55 | *ptr = dlsym(lib->handle, name); 56 | return uv__dlerror(lib); 57 | } 58 | 59 | 60 | const char* uv_dlerror(const uv_lib_t* lib) { 61 | return lib->errmsg ? lib->errmsg : "no error"; 62 | } 63 | 64 | 65 | static int uv__dlerror(uv_lib_t* lib) { 66 | const char* errmsg; 67 | 68 | uv__free(lib->errmsg); 69 | 70 | errmsg = dlerror(); 71 | 72 | if (errmsg) { 73 | lib->errmsg = uv__strdup(errmsg); 74 | return -1; 75 | } 76 | else { 77 | lib->errmsg = NULL; 78 | return 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/os390-syscalls.h: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | 23 | #ifndef UV_OS390_SYSCALL_H_ 24 | #define UV_OS390_SYSCALL_H_ 25 | 26 | #include "uv.h" 27 | #include "internal.h" 28 | #include 29 | #include 30 | #include 31 | 32 | #define EPOLL_CTL_ADD 1 33 | #define EPOLL_CTL_DEL 2 34 | #define EPOLL_CTL_MOD 3 35 | #define MAX_EPOLL_INSTANCES 256 36 | #define MAX_ITEMS_PER_EPOLL 1024 37 | 38 | #define UV__O_CLOEXEC 0x80000 39 | #define UV__EPOLL_CLOEXEC UV__O_CLOEXEC 40 | #define UV__EPOLL_CTL_ADD EPOLL_CTL_ADD 41 | #define UV__EPOLL_CTL_DEL EPOLL_CTL_DEL 42 | #define UV__EPOLL_CTL_MOD EPOLL_CTL_MOD 43 | 44 | struct epoll_event { 45 | int events; 46 | int fd; 47 | }; 48 | 49 | typedef struct { 50 | QUEUE member; 51 | struct pollfd* items; 52 | unsigned long size; 53 | } uv__os390_epoll; 54 | 55 | /* epoll api */ 56 | uv__os390_epoll* epoll_create1(int flags); 57 | int epoll_ctl(uv__os390_epoll* ep, int op, int fd, struct epoll_event *event); 58 | int epoll_wait(uv__os390_epoll* ep, struct epoll_event *events, int maxevents, int timeout); 59 | int epoll_file_close(int fd); 60 | 61 | /* utility functions */ 62 | int nanosleep(const struct timespec* req, struct timespec* rem); 63 | int scandir(const char* maindir, struct dirent*** namelist, 64 | int (*filter)(const struct dirent *), 65 | int (*compar)(const struct dirent **, 66 | const struct dirent **)); 67 | char *mkdtemp(char* path); 68 | 69 | #endif /* UV_OS390_SYSCALL_H_ */ 70 | -------------------------------------------------------------------------------- /docs/thread.rst: -------------------------------------------------------------------------------- 1 | .. _thread: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | =========================================================== 8 | :py:mod:`pyuv.thread` --- Thread synchronization primitives 9 | =========================================================== 10 | 11 | 12 | .. py:class:: pyuv.thread.Barrier(count) 13 | 14 | :param int count: Initialize the barrier for the given amount of threads 15 | 16 | .. py:method:: wait 17 | 18 | Synchronize all the participating threads at the barrier. 19 | 20 | 21 | .. py:class:: pyuv.thread.Mutex 22 | 23 | .. py:method:: lock 24 | 25 | Lock this mutex. 26 | 27 | .. py:method:: unlock 28 | 29 | Unlock this mutex. 30 | 31 | .. py:method:: trylock 32 | 33 | Try to lock the mutex. If the lock could be acquired True is returned, False otherwise. 34 | 35 | 36 | .. py:class:: pyuv.thread.RWLock 37 | 38 | .. py:method:: rdlock 39 | 40 | Lock this rwlock for reading. 41 | 42 | .. py:method:: rdunlock 43 | 44 | Unlock this rwlock for reading. 45 | 46 | .. py:method:: tryrdlock 47 | 48 | Try to lock the rwlock for reading. If the lock could be acquired True is returned, False otherwise. 49 | 50 | .. py:method:: wrlock 51 | 52 | Lock this rwlock for writing. 53 | 54 | .. py:method:: wrunlock 55 | 56 | Unlock this rwlock for writing. 57 | 58 | .. py:method:: trywrlock 59 | 60 | Try to lock the rwlock for writing. If the lock could be acquired True is returned, False otherwise. 61 | 62 | 63 | .. py:class:: pyuv.thread.Condition(lock) 64 | 65 | :param Mutex lock: Lock to be used by this condition. 66 | 67 | .. py:method:: signal 68 | 69 | Unblock at least one of the threads that are blocked on this condition. 70 | 71 | .. py:method:: broadcast 72 | 73 | Unblock all threads blocked on this condition. 74 | 75 | .. py:method:: wait 76 | 77 | Block on this condition variable, the mutex lock must be held. 78 | 79 | .. py:method:: timedwait(timeout) 80 | 81 | :param double timeout: Time to wait until condition is met before giving up. 82 | 83 | Wait for the condition to be met, give up after the specified timeout. 84 | 85 | 86 | .. py:class:: pyuv.thread.Semaphore(count=1) 87 | 88 | :param int count: Initialize the semaphore with the given counter value. 89 | 90 | .. py:method:: post 91 | 92 | Increment (unlock) the semaphore. 93 | 94 | .. py:method:: wait 95 | 96 | Decrement (lock) the semaphore. 97 | 98 | .. py:method:: trywait 99 | 100 | Try to decrement (lock) the semaphore. If the counter could be decremented True is returned, False otherwise. 101 | 102 | 103 | -------------------------------------------------------------------------------- /tests/test_timer.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | import warnings 4 | 5 | from common import TestCase 6 | import pyuv 7 | 8 | 9 | class TimerTest(TestCase): 10 | 11 | def test_timer1(self): 12 | self.timer_cb_called = 0 13 | def timer_cb(timer): 14 | self.timer_cb_called += 1 15 | timer.stop() 16 | timer.close() 17 | timer = pyuv.Timer(self.loop) 18 | timer.start(timer_cb, 0.1, 0) 19 | self.loop.run() 20 | self.assertEqual(self.timer_cb_called, 1) 21 | 22 | def test_timer_never(self): 23 | self.timer_cb_called = 0 24 | def timer_cb(timer): 25 | self.timer_cb_called += 1 26 | timer.stop() 27 | timer.close() 28 | timer = pyuv.Timer(self.loop) 29 | timer.start(timer_cb, 0.1, 0) 30 | timer.close() 31 | self.loop.run() 32 | self.assertEqual(self.timer_cb_called, 0) 33 | 34 | def test_timer_ref1(self): 35 | self.timer_cb_called = 0 36 | def timer_cb(timer): 37 | self.timer_cb_called += 1 38 | timer.stop() 39 | timer.close() 40 | self.timer = pyuv.Timer(self.loop) 41 | self.loop.run() 42 | self.assertEqual(self.timer_cb_called, 0) 43 | 44 | def test_timer_ref2(self): 45 | self.timer_cb_called = 0 46 | def timer_cb(timer): 47 | self.timer_cb_called += 1 48 | timer.stop() 49 | timer.close() 50 | self.timer = pyuv.Timer(self.loop) 51 | self.timer.start(timer_cb, 0.1, 0) 52 | self.timer.ref = False 53 | self.loop.run() 54 | self.assertEqual(self.timer_cb_called, 0) 55 | self.timer.ref = True 56 | self.loop.run() 57 | self.assertEqual(self.timer_cb_called, 1) 58 | 59 | def test_timer_noref(self): 60 | self.timer_cb_called = 0 61 | def timer_cb(timer): 62 | self.timer_cb_called += 1 63 | timer.close() 64 | t = pyuv.Timer(self.loop) 65 | t.start(timer_cb, 0.1, 0) 66 | t = None 67 | self.loop.run() 68 | self.assertEqual(self.timer_cb_called, 1) 69 | 70 | def test_timer_submillisecond(self): 71 | self.timer_cb_called = 0 72 | def timer_cb(timer): 73 | self.timer_cb_called += 1 74 | timer.close() 75 | t = pyuv.Timer(self.loop) 76 | with warnings.catch_warnings(record=True) as w: 77 | # Cause all warnings to always be triggered 78 | warnings.simplefilter('always') 79 | 80 | t.start(timer_cb, 0.00001, 0) 81 | 82 | self.assertEqual(len(w), 1) 83 | self.assertTrue(issubclass(w[0].category, RuntimeWarning)) 84 | self.loop.run() 85 | self.assertEqual(self.timer_cb_called, 1) 86 | 87 | 88 | if __name__ == '__main__': 89 | unittest.main(verbosity=2) 90 | -------------------------------------------------------------------------------- /docs/error.rst: -------------------------------------------------------------------------------- 1 | .. _error: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ============================================== 8 | :py:mod:`pyuv.error` --- Exception definitions 9 | ============================================== 10 | 11 | 12 | This module contains the definition of the different exceptions that 13 | are used throughout `puyv`. 14 | 15 | 16 | .. py:exception:: UVError() 17 | 18 | Base exception class. Parent of all other exception classes. 19 | 20 | .. py:exception:: ThreadError() 21 | 22 | Exception raised by thread module operations. 23 | 24 | .. py:exception:: HandleError() 25 | 26 | Base exception class. Parent of all other handle exception classes. 27 | 28 | .. py:exception:: HandleClosedError() 29 | 30 | Exception raised if a handle is already closed and some function is called on it. 31 | 32 | .. py:exception:: StreamError() 33 | 34 | Base exception class for stream errors. 35 | 36 | .. py:exception:: AsyncError() 37 | 38 | Exception raised if an error is found when calling ``Async`` handle functions. 39 | 40 | .. py:exception:: CheckError() 41 | 42 | Exception raised if an error is found when calling ``Check`` handle functions. 43 | 44 | .. py:exception:: DNSError() 45 | 46 | Exception raised if an error is found when calling ``DNSResolver`` functions. 47 | 48 | .. py:exception:: FSError() 49 | 50 | Exception raised if an error is found when calling funcions from the :py:mod:`fs` module. 51 | 52 | .. py:exception:: FSEventError() 53 | 54 | Exception raised if an error is found when calling ``FSEvent`` handle functions. 55 | 56 | .. py:exception:: IdleError() 57 | 58 | Exception raised if an error is found when calling ``Idle`` handle functions. 59 | 60 | .. py:exception:: PipeError() 61 | 62 | Exception raised if an error is found when calling ``Pipe`` handle functions. 63 | 64 | .. py:exception:: PrepareError() 65 | 66 | Exception raised if an error is found when calling ``Prepare`` handle functions. 67 | 68 | .. py:exception:: PollError() 69 | 70 | Exception raised if an error is found when calling ``Poll`` handle functions. 71 | 72 | .. py:exception:: SignalError() 73 | 74 | Exception raised if an error is found when calling ``Signal`` handle functions. 75 | 76 | .. py:exception:: TCPError() 77 | 78 | Exception raised if an error is found when calling ``TCP`` handle functions. 79 | 80 | .. py:exception:: TimerError() 81 | 82 | Exception raised if an error is found when calling ``Timer`` handle functions. 83 | 84 | .. py:exception:: UDPError() 85 | 86 | Exception raised if an error is found when calling ``UDP`` handle functions. 87 | 88 | .. py:exception:: TTYError() 89 | 90 | Exception raised if an error is found when calling ``TTY`` handle functions. 91 | 92 | .. py:exception:: ProcessError() 93 | 94 | Exception raised if an error is found when calling ``Process`` handle functions. 95 | 96 | -------------------------------------------------------------------------------- /tests/test_threadpool.py: -------------------------------------------------------------------------------- 1 | 2 | import functools 3 | import sys 4 | import threading 5 | import time 6 | import unittest 7 | 8 | from common import TestCase 9 | import pyuv 10 | 11 | 12 | class WorkItem(object): 13 | 14 | def __init__(self, func, *args, **kw): 15 | self._cb = functools.partial(func, *args, **kw) 16 | self.result = None 17 | self.exc_info = None 18 | 19 | def __call__(self): 20 | try: 21 | self._cb() 22 | except Exception: 23 | self.exc_info = sys.exc_info() 24 | finally: 25 | self._cb = None 26 | 27 | 28 | class ThreadPoolTest(TestCase): 29 | 30 | def setUp(self): 31 | super(ThreadPoolTest, self).setUp() 32 | self.pool_cb_called = 0 33 | self.pool_after_work_cb_called = 0 34 | 35 | def run_in_pool(self, *args, **kw): 36 | self.pool_cb_called += 1 37 | time.sleep(0.1) 38 | 39 | def after_work_cb(self, error): 40 | self.assertEqual(error, None) 41 | self.pool_after_work_cb_called += 1 42 | 43 | def test_threadpool1(self): 44 | self.loop.queue_work(self.run_in_pool, self.after_work_cb) 45 | args = (1, 2, 3) 46 | kw = {} 47 | self.loop.queue_work(functools.partial(self.run_in_pool, *args, **kw), self.after_work_cb) 48 | args = () 49 | kw = {'test': 1} 50 | self.loop.queue_work(functools.partial(self.run_in_pool, *args, **kw), self.after_work_cb) 51 | self.loop.run() 52 | self.assertEqual(self.pool_cb_called, 3) 53 | self.assertEqual(self.pool_after_work_cb_called, 3) 54 | 55 | def raise_in_pool(self, *args, **kw): 56 | 1/0 57 | 58 | def after_work_cb2(self, error): 59 | self.assertEqual(error, None) 60 | self.assertEqual(self.work_item.exc_info[0], ZeroDivisionError) 61 | 62 | def test_threadpool_exc(self): 63 | self.work_item = WorkItem(self.raise_in_pool) 64 | self.loop.queue_work(self.work_item, self.after_work_cb2) 65 | self.loop.run() 66 | 67 | 68 | class ThreadPoolMultiLoopTest(unittest.TestCase): 69 | 70 | def setUp(self): 71 | self.pool_cb_called = 0 72 | self.lock = threading.Lock() 73 | 74 | def run_in_pool(self): 75 | with self.lock: 76 | self.pool_cb_called += 1 77 | time.sleep(0.2) 78 | 79 | def run_loop(self): 80 | loop = pyuv.Loop() 81 | loop.queue_work(self.run_in_pool) 82 | loop.run() 83 | 84 | def test_threadpool_multiple_loops(self): 85 | t1 = threading.Thread(target=self.run_loop) 86 | t2 = threading.Thread(target=self.run_loop) 87 | t3 = threading.Thread(target=self.run_loop) 88 | [t.start() for t in (t1, t2, t3)] 89 | [t.join(5) for t in (t1, t2, t3)] 90 | self.assertEqual(self.pool_cb_called, 3) 91 | 92 | 93 | if __name__ == '__main__': 94 | unittest.main(verbosity=2) 95 | 96 | -------------------------------------------------------------------------------- /docs/util.rst: -------------------------------------------------------------------------------- 1 | .. _util: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ============================================== 8 | :py:mod:`pyuv.util` --- Miscelaneous utilities 9 | ============================================== 10 | 11 | 12 | .. py:function:: pyuv.util.hrtime 13 | 14 | Get the high-resolution system time. It's given in nanoseconds, even if the 15 | system doesn't support nanosecond precision. 16 | 17 | .. py:function:: pyuv.util.get_free_memory 18 | 19 | Get the system free memory (in bytes). 20 | 21 | .. py:function:: pyuv.util.get_total_memory 22 | 23 | Get the system total memory (in bytes). 24 | 25 | .. py:function:: pyuv.util.loadavg 26 | 27 | Get the system load average. 28 | 29 | .. py:function:: pyuv.util.uptime 30 | 31 | Get the current uptime. 32 | 33 | .. py:function:: pyuv.util.resident_set_size 34 | 35 | Get the current resident memory size. 36 | 37 | .. py:function:: pyuv.util.interface_addresses 38 | 39 | Get interface addresses information. 40 | 41 | .. py:function:: pyuv.util.cpu_info 42 | 43 | Get CPUs information. 44 | 45 | .. py:function:: pyuv.util.getrusage 46 | 47 | Get information about resource utilization. getrusage(2) implementation 48 | which always uses RUSAGE_SELF. Limited support on Windows. 49 | 50 | .. py:function:: pyuv.util.guess_handle_type 51 | 52 | Given a file descriptor, returns the handle type in the form of a constant (integer). 53 | The user can compare it with constants exposed in pyuv.*, such as UV_TTY, UV_TCP, and so on. 54 | 55 | .. py:class:: pyuv.util.SignalChecker(loop, fd) 56 | 57 | :type loop: :py:class:`Loop` 58 | :param loop: loop object where this handle runs (accessible through :py:attr:`SignalChecker.loop`). 59 | 60 | :param int fd: File descriptor to be monitored for readability. 61 | 62 | `SignalChecker` is a handle which can be used to interact with signals set up by the standard `signal` module. 63 | 64 | Here is how it works: the user is required to get a pair of file descriptors and put them in nonblocking mode. These descriptors can be either 65 | a `os.pipe()`, a `socket.socketpair()` or a manually made pair of connected sockets. One of these descriptors will be used just for 66 | writing, and the other end for reading. The user must use `signal.set_wakeup_fd` and register the write descriptor. The read descriptor 67 | must be passed to this handle. When the process receives a signal Python will write on the write end of the socket pair and it will cause 68 | the SignalChecker to wakeup the loop and call the Python C API function to process signals: `PyErr_CheckSignals`. 69 | 70 | It's better to use the `Signal` handle also provided by this library, because it doesn't need any work from the user and it works on any thread. This 71 | handle merely exists for some cases which you don't probably care about, or if you want to use the `signal` module directly. 72 | 73 | .. py:method:: start 74 | 75 | Start the signal checking handle. 76 | 77 | .. py:method:: stop 78 | 79 | Stop the signal checking handle. 80 | 81 | -------------------------------------------------------------------------------- /docs/poll.rst: -------------------------------------------------------------------------------- 1 | .. _poll: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ================================ 8 | :py:class:`Poll` --- Poll handle 9 | ================================ 10 | 11 | 12 | .. py:class:: Poll(loop, fd) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`Poll.loop`). 16 | 17 | :param int fd: File descriptor to be monitored for readability or writability. 18 | 19 | ``Poll`` handles can be used to monitor an arbitrary file descriptor for readability or writability. 20 | On Unix any file descriptor is supported but on Windows only sockets are supported. 21 | 22 | .. note:: 23 | (From the libuv documentation) 24 | The uv_poll watcher is used to watch file descriptors for readability and 25 | writability, similar to the purpose of poll(2). 26 | 27 | The purpose of uv_poll is to enable integrating external libraries that 28 | rely on the event loop to signal it about the socket status changes, like 29 | c-ares or libssh2. Using uv_poll_t for any other other purpose is not 30 | recommended; uv_tcp_t, uv_udp_t, etc. provide an implementation that is 31 | much faster and more scalable than what can be achieved with uv_poll_t, 32 | especially on Windows. 33 | 34 | It is possible that uv_poll occasionally signals that a file descriptor is 35 | readable or writable even when it isn't. The user should therefore always 36 | be prepared to handle EAGAIN or equivalent when it attempts to read from or 37 | write to the fd. 38 | 39 | The user should not close a file descriptor while it is being polled by an 40 | active uv_poll watcher. This can cause the poll watcher to report an error, 41 | but it might also start polling another socket. However the fd can be safely 42 | closed immediately after a call to uv_poll_stop() or uv_close(). 43 | 44 | On windows only sockets can be polled with uv_poll. On unix any file 45 | descriptor that would be accepted by poll(2) can be used with uv_poll. 46 | 47 | IMPORTANT: It is not okay to have multiple active uv_poll watchers for the same socket. 48 | This can cause libuv to assert. See this issue: https://github.com/saghul/pyuv/issues/54 49 | 50 | .. py:method:: start(events, callback) 51 | 52 | :param int events: Mask of events that will be detected. The possible events are `pyuv.UV_READABLE` 53 | `pyuv.UV_WRITABLE`, or `pyuv.UV_DISCONNECT`. 54 | :param callable callback: Function that will be called when the ``Poll`` 55 | handle receives events. 56 | 57 | Start or update the event mask of the ``Poll`` handle. 58 | 59 | Callback signature: ``callback(poll_handle, events, errorno)``. 60 | 61 | .. note:: 62 | The ``UV_DISCONNECT`` event might not be triggered on all platforms. 63 | 64 | .. py:method:: stop 65 | 66 | Stop the ``Poll`` handle. 67 | 68 | .. py:method:: fileno 69 | 70 | Returns the file descriptor being monitored or -1 if the handle is closed. 71 | 72 | -------------------------------------------------------------------------------- /deps/libuv/src/win/async.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include 23 | 24 | #include "uv.h" 25 | #include "internal.h" 26 | #include "atomicops-inl.h" 27 | #include "handle-inl.h" 28 | #include "req-inl.h" 29 | 30 | 31 | void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { 32 | if (handle->flags & UV__HANDLE_CLOSING && 33 | !handle->async_sent) { 34 | assert(!(handle->flags & UV_HANDLE_CLOSED)); 35 | uv__handle_close(handle); 36 | } 37 | } 38 | 39 | 40 | int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { 41 | uv_req_t* req; 42 | 43 | uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); 44 | handle->async_sent = 0; 45 | handle->async_cb = async_cb; 46 | 47 | req = &handle->async_req; 48 | UV_REQ_INIT(req, UV_WAKEUP); 49 | req->data = handle; 50 | 51 | uv__handle_start(handle); 52 | 53 | return 0; 54 | } 55 | 56 | 57 | void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { 58 | if (!((uv_async_t*)handle)->async_sent) { 59 | uv_want_endgame(loop, (uv_handle_t*) handle); 60 | } 61 | 62 | uv__handle_closing(handle); 63 | } 64 | 65 | 66 | int uv_async_send(uv_async_t* handle) { 67 | uv_loop_t* loop = handle->loop; 68 | 69 | if (handle->type != UV_ASYNC) { 70 | /* Can't set errno because that's not thread-safe. */ 71 | return -1; 72 | } 73 | 74 | /* The user should make sure never to call uv_async_send to a closing */ 75 | /* or closed handle. */ 76 | assert(!(handle->flags & UV__HANDLE_CLOSING)); 77 | 78 | if (!uv__atomic_exchange_set(&handle->async_sent)) { 79 | POST_COMPLETION_FOR_REQ(loop, &handle->async_req); 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | 86 | void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, 87 | uv_req_t* req) { 88 | assert(handle->type == UV_ASYNC); 89 | assert(req->type == UV_WAKEUP); 90 | 91 | handle->async_sent = 0; 92 | 93 | if (handle->flags & UV__HANDLE_CLOSING) { 94 | uv_want_endgame(loop, (uv_handle_t*)handle); 95 | } else if (handle->async_cb != NULL) { 96 | handle->async_cb(handle); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /docs/tty.rst: -------------------------------------------------------------------------------- 1 | .. _tty: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ========================================== 8 | :py:class:`TTY` --- TTY controlling handle 9 | ========================================== 10 | 11 | 12 | .. py:class:: TTY(loop, fd, readable) 13 | 14 | :type loop: :py:class:`Loop` 15 | :param loop: loop object where this handle runs (accessible through :py:attr:`TTY.loop`). 16 | :param int fd: File descriptor to be opened as a TTY. 17 | :param bool readable: Specifies if the given fd is readable. 18 | 19 | The ``TTY`` handle provides asynchronous stdin / stdout functionality. 20 | 21 | .. py:method:: shutdown([callback]) 22 | 23 | :param callable callback: Callback to be called after shutdown has been performed. 24 | 25 | Shutdown the outgoing (write) direction of the ``TTY`` connection. 26 | 27 | Callback signature: ``callback(tty_handle)``. 28 | 29 | .. py:method:: write(data, [callback]) 30 | 31 | :param object data: Data to be written on the ``TTY`` connection. It can be any Python object conforming 32 | to the buffer interface or a sequence of such objects. 33 | 34 | :param callable callback: Callback to be called after the write operation 35 | has been performed. 36 | 37 | Write data on the ``TTY`` connection. 38 | 39 | Callback signature: ``callback(tcp_handle, error)``. 40 | 41 | .. py:method:: try_write(data) 42 | 43 | :param object data: Data to be written on the ``TTY`` connection. It can be any Python object conforming 44 | to the buffer interface. 45 | 46 | Try to write data on the ``TTY`` connection. It will raise an exception if data cannot be written immediately 47 | or a number indicating the amount of data written. 48 | 49 | .. py:method:: start_read(callback) 50 | 51 | :param callable callback: Callback to be called when data is read. 52 | 53 | Start reading for incoming data. 54 | 55 | Callback signature: ``callback(status_handle, data)``. 56 | 57 | .. py:method:: stop_read 58 | 59 | Stop reading data. 60 | 61 | .. py:method:: set_mode(mode) 62 | 63 | :param int mode: TTY mode. 0 for normal, 1 for raw. 64 | 65 | Set TTY mode. 66 | 67 | .. py:method:: get_winsize 68 | 69 | Get terminal window size. 70 | 71 | .. py:method:: fileno 72 | 73 | Return the internal file descriptor (or HANDLE in Windows) used by the 74 | ``TTY`` handle. 75 | 76 | .. warning:: 77 | libuv expects you not to modify the file descriptor in any way, and 78 | if you do, things will very likely break. 79 | 80 | .. py:classmethod:: reset_mode 81 | 82 | Reset TTY settings. To be called when program exits. 83 | 84 | .. py:attribute:: write_queue_size 85 | 86 | *Read only* 87 | 88 | Returns the size of the write queue. 89 | 90 | .. py:attribute:: readable 91 | 92 | *Read only* 93 | 94 | Indicates if this handle is readable. 95 | 96 | .. py:attribute:: writable 97 | 98 | *Read only* 99 | 100 | Indicates if this handle is writable. 101 | 102 | -------------------------------------------------------------------------------- /tests/test_poll.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import errno 4 | import socket 5 | import sys 6 | import unittest 7 | 8 | from common import linesep, TestCase 9 | import pyuv 10 | 11 | 12 | TEST_PORT = 1234 13 | 14 | if sys.platform == "win32": 15 | NONBLOCKING = (errno.WSAEWOULDBLOCK,) 16 | else: 17 | NONBLOCKING = (errno.EAGAIN, errno.EINPROGRESS, errno.EWOULDBLOCK) 18 | 19 | 20 | class PollTest(TestCase): 21 | 22 | def setUp(self): 23 | super(PollTest, self).setUp() 24 | self.poll = None 25 | self.server = None 26 | self.sock = None 27 | self.client_connection = None 28 | self.connecting = False 29 | 30 | def on_connection(self, server, error): 31 | self.assertEqual(error, None) 32 | client = pyuv.TCP(self.loop) 33 | server.accept(client) 34 | self.client_connection = client 35 | client.start_read(self.on_client_connection_read) 36 | client.write(b"PING"+linesep) 37 | 38 | def on_client_connection_read(self, client, data, error): 39 | self.assertEqual(data, b"PONG"+linesep) 40 | self.poll.close() 41 | self.client_connection.close() 42 | self.server.close() 43 | 44 | def poll_cb(self, handle, events, error): 45 | if self.connecting: 46 | err = self.sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) 47 | if not err: 48 | self.connecting = False 49 | self.poll.stop() 50 | self.poll.start(pyuv.UV_READABLE, self.poll_cb) 51 | elif err in NONBLOCKING: 52 | return 53 | else: 54 | self.poll.close() 55 | self.client_connection.close() 56 | self.server.close() 57 | self.fail("Error connecting socket: %d" % err) 58 | return 59 | if (events & pyuv.UV_READABLE): 60 | self.poll.stop() 61 | data = self.sock.recv(1024) 62 | self.assertEqual(data, b"PING"+linesep) 63 | self.poll.start(pyuv.UV_WRITABLE, self.poll_cb) 64 | elif (events & pyuv.UV_WRITABLE): 65 | self.poll.stop() 66 | self.sock.send(b"PONG"+linesep) 67 | 68 | def test_poll(self): 69 | self.server = pyuv.TCP(self.loop) 70 | self.server.bind(("0.0.0.0", TEST_PORT)) 71 | self.server.listen(self.on_connection) 72 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 73 | self.sock.setblocking(False) 74 | while True: 75 | r = self.sock.connect_ex(("127.0.0.1", TEST_PORT)) 76 | if r and r != errno.EINTR: 77 | break 78 | if r not in NONBLOCKING: 79 | self.server.close() 80 | self.fail("Error connecting socket: %d" % r) 81 | return 82 | self.connecting = True 83 | self.poll = pyuv.Poll(self.loop, self.sock.fileno()) 84 | self.assertEqual(self.sock.fileno(), self.poll.fileno()) 85 | self.poll.start(pyuv.UV_WRITABLE, self.poll_cb) 86 | self.loop.run() 87 | self.assertTrue(self.poll.closed) 88 | self.assertRaises(pyuv.error.HandleClosedError, self.poll.fileno) 89 | self.sock.close() 90 | 91 | 92 | if __name__ == '__main__': 93 | unittest.main(verbosity=2) 94 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | global: 3 | # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the 4 | # /E:ON and /V:ON options are not enabled in the batch script intepreter 5 | # See: http://stackoverflow.com/a/13751649/163740 6 | CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" 7 | 8 | matrix: 9 | - PYTHON: "C:\\Python27" 10 | PYTHON_VERSION: "2.7.x" # currently 2.7.9 11 | PYTHON_ARCH: "32" 12 | 13 | - PYTHON: "C:\\Python27-x64" 14 | PYTHON_VERSION: "2.7.x" # currently 2.7.9 15 | PYTHON_ARCH: "64" 16 | 17 | - PYTHON: "C:\\Python33" 18 | PYTHON_VERSION: "3.3.x" # currently 3.3.5 19 | PYTHON_ARCH: "32" 20 | 21 | - PYTHON: "C:\\Python33-x64" 22 | PYTHON_VERSION: "3.3.x" # currently 3.3.5 23 | PYTHON_ARCH: "64" 24 | 25 | - PYTHON: "C:\\Python34" 26 | PYTHON_VERSION: "3.4.x" # currently 3.4.3 27 | PYTHON_ARCH: "32" 28 | 29 | - PYTHON: "C:\\Python34-x64" 30 | PYTHON_VERSION: "3.4.x" # currently 3.4.3 31 | PYTHON_ARCH: "64" 32 | 33 | - PYTHON: "C:\\Python35" 34 | PYTHON_VERSION: "3.5.x" # currently 3.5.1 35 | PYTHON_ARCH: "32" 36 | 37 | - PYTHON: "C:\\Python35-x64" 38 | PYTHON_VERSION: "3.5.x" # currently 3.5.1 39 | PYTHON_ARCH: "64" 40 | 41 | - PYTHON: "C:\\Python36" 42 | PYTHON_VERSION: "3.6.x" 43 | PYTHON_ARCH: "32" 44 | 45 | - PYTHON: "C:\\Python36-x64" 46 | PYTHON_VERSION: "3.6.x" 47 | PYTHON_ARCH: "64" 48 | 49 | branches: 50 | only: 51 | - master 52 | - v1.x 53 | 54 | install: 55 | - ECHO "Filesystem root:" 56 | - ps: "ls \"C:/\"" 57 | 58 | - ECHO "Installed SDKs:" 59 | - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" 60 | 61 | # Install Python (from the official .msi of http://python.org) and pip when 62 | # not already installed. 63 | - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } 64 | 65 | # Prepend newly installed Python to the PATH of this build (this cannot be 66 | # done from inside the powershell script as it would require to restart 67 | # the parent CMD process). 68 | - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" 69 | 70 | # Check that we have the expected version and architecture for Python 71 | - "python --version" 72 | - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" 73 | 74 | # Upgrade to the latest version of pip 75 | - "pip install --disable-pip-version-check --user --upgrade pip" 76 | 77 | # Install wheel 78 | - "%CMD_IN_ENV% pip install wheel" 79 | 80 | # Install dev requirements 81 | - "%CMD_IN_ENV% pip install -r dev-requirements.txt" 82 | 83 | build: false # Not a C# project, build stuff at the test step instead. 84 | 85 | test_script: 86 | # Build the compiled extension and run the project tests 87 | - "%CMD_IN_ENV% python setup.py build_ext --inplace" 88 | - "%CMD_IN_ENV% nosetests -v" 89 | 90 | after_test: 91 | # If tests are successful, create binary packages for the project. 92 | - "%CMD_IN_ENV% python setup.py bdist_wheel" 93 | - ps: "ls dist" 94 | 95 | artifacts: 96 | # Archive the generated packages in the ci.appveyor.com build report. 97 | - path: dist\*.whl 98 | 99 | #on_success: 100 | # - TODO: upload the content of dist/*.whl to a public wheelhouse 101 | # 102 | -------------------------------------------------------------------------------- /deps/libuv/include/uv-darwin.h: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #ifndef UV_DARWIN_H 23 | #define UV_DARWIN_H 24 | 25 | #if defined(__APPLE__) && defined(__MACH__) 26 | # include 27 | # include 28 | # include 29 | # include 30 | # define UV_PLATFORM_SEM_T semaphore_t 31 | #endif 32 | 33 | #define UV_IO_PRIVATE_PLATFORM_FIELDS \ 34 | int rcount; \ 35 | int wcount; \ 36 | 37 | #define UV_PLATFORM_LOOP_FIELDS \ 38 | uv_thread_t cf_thread; \ 39 | void* _cf_reserved; \ 40 | void* cf_state; \ 41 | uv_mutex_t cf_mutex; \ 42 | uv_sem_t cf_sem; \ 43 | void* cf_signals[2]; \ 44 | 45 | #define UV_PLATFORM_FS_EVENT_FIELDS \ 46 | uv__io_t event_watcher; \ 47 | char* realpath; \ 48 | int realpath_len; \ 49 | int cf_flags; \ 50 | uv_async_t* cf_cb; \ 51 | void* cf_events[2]; \ 52 | void* cf_member[2]; \ 53 | int cf_error; \ 54 | uv_mutex_t cf_mutex; \ 55 | 56 | #define UV_STREAM_PRIVATE_PLATFORM_FIELDS \ 57 | void* select; \ 58 | 59 | #define UV_HAVE_KQUEUE 1 60 | 61 | #endif /* UV_DARWIN_H */ 62 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/pthread-barrier.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016, Kari Tristan Helgason 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | #include "uv-common.h" 17 | #include "pthread-barrier.h" 18 | 19 | #include 20 | #include 21 | 22 | /* TODO: support barrier_attr */ 23 | int pthread_barrier_init(pthread_barrier_t* barrier, 24 | const void* barrier_attr, 25 | unsigned count) { 26 | int rc; 27 | _uv_barrier* b; 28 | 29 | if (barrier == NULL || count == 0) 30 | return EINVAL; 31 | 32 | if (barrier_attr != NULL) 33 | return ENOTSUP; 34 | 35 | b = uv__malloc(sizeof(*b)); 36 | if (b == NULL) 37 | return ENOMEM; 38 | 39 | b->in = 0; 40 | b->out = 0; 41 | b->threshold = count; 42 | 43 | if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0) 44 | goto error2; 45 | if ((rc = pthread_cond_init(&b->cond, NULL)) != 0) 46 | goto error; 47 | 48 | barrier->b = b; 49 | return 0; 50 | 51 | error: 52 | pthread_mutex_destroy(&b->mutex); 53 | error2: 54 | uv__free(b); 55 | return rc; 56 | } 57 | 58 | int pthread_barrier_wait(pthread_barrier_t* barrier) { 59 | int rc; 60 | _uv_barrier* b; 61 | 62 | if (barrier == NULL || barrier->b == NULL) 63 | return EINVAL; 64 | 65 | b = barrier->b; 66 | /* Lock the mutex*/ 67 | if ((rc = pthread_mutex_lock(&b->mutex)) != 0) 68 | return rc; 69 | 70 | /* Increment the count. If this is the first thread to reach the threshold, 71 | wake up waiters, unlock the mutex, then return 72 | PTHREAD_BARRIER_SERIAL_THREAD. */ 73 | if (++b->in == b->threshold) { 74 | b->in = 0; 75 | b->out = b->threshold - 1; 76 | rc = pthread_cond_signal(&b->cond); 77 | assert(rc == 0); 78 | 79 | pthread_mutex_unlock(&b->mutex); 80 | return PTHREAD_BARRIER_SERIAL_THREAD; 81 | } 82 | /* Otherwise, wait for other threads until in is set to 0, 83 | then return 0 to indicate this is not the first thread. */ 84 | do { 85 | if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0) 86 | break; 87 | } while (b->in != 0); 88 | 89 | /* mark thread exit */ 90 | b->out--; 91 | pthread_cond_signal(&b->cond); 92 | pthread_mutex_unlock(&b->mutex); 93 | return rc; 94 | } 95 | 96 | int pthread_barrier_destroy(pthread_barrier_t* barrier) { 97 | int rc; 98 | _uv_barrier* b; 99 | 100 | if (barrier == NULL || barrier->b == NULL) 101 | return EINVAL; 102 | 103 | b = barrier->b; 104 | 105 | if ((rc = pthread_mutex_lock(&b->mutex)) != 0) 106 | return rc; 107 | 108 | if (b->in > 0 || b->out > 0) 109 | rc = EBUSY; 110 | 111 | pthread_mutex_unlock(&b->mutex); 112 | 113 | if (rc) 114 | return rc; 115 | 116 | pthread_cond_destroy(&b->cond); 117 | pthread_mutex_destroy(&b->mutex); 118 | uv__free(barrier->b); 119 | barrier->b = NULL; 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/proctitle.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * Permission is hereby granted, free of charge, to any person obtaining a copy 3 | * of this software and associated documentation files (the "Software"), to 4 | * deal in the Software without restriction, including without limitation the 5 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | * sell copies of the Software, and to permit persons to whom the Software is 7 | * furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in 10 | * all copies or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | * IN THE SOFTWARE. 19 | */ 20 | 21 | #include "uv.h" 22 | #include "internal.h" 23 | 24 | #include 25 | #include 26 | 27 | extern void uv__set_process_title(const char* title); 28 | 29 | static void* args_mem; 30 | 31 | static struct { 32 | char* str; 33 | size_t len; 34 | } process_title; 35 | 36 | 37 | char** uv_setup_args(int argc, char** argv) { 38 | char** new_argv; 39 | size_t size; 40 | char* s; 41 | int i; 42 | 43 | if (argc <= 0) 44 | return argv; 45 | 46 | /* Calculate how much memory we need for the argv strings. */ 47 | size = 0; 48 | for (i = 0; i < argc; i++) 49 | size += strlen(argv[i]) + 1; 50 | 51 | #if defined(__MVS__) 52 | /* argv is not adjacent. So just use argv[0] */ 53 | process_title.str = argv[0]; 54 | process_title.len = strlen(argv[0]); 55 | #else 56 | process_title.str = argv[0]; 57 | process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]; 58 | assert(process_title.len + 1 == size); /* argv memory should be adjacent. */ 59 | #endif 60 | 61 | /* Add space for the argv pointers. */ 62 | size += (argc + 1) * sizeof(char*); 63 | 64 | new_argv = uv__malloc(size); 65 | if (new_argv == NULL) 66 | return argv; 67 | args_mem = new_argv; 68 | 69 | /* Copy over the strings and set up the pointer table. */ 70 | s = (char*) &new_argv[argc + 1]; 71 | for (i = 0; i < argc; i++) { 72 | size = strlen(argv[i]) + 1; 73 | memcpy(s, argv[i], size); 74 | new_argv[i] = s; 75 | s += size; 76 | } 77 | new_argv[i] = NULL; 78 | 79 | return new_argv; 80 | } 81 | 82 | 83 | int uv_set_process_title(const char* title) { 84 | if (process_title.len == 0) 85 | return 0; 86 | 87 | /* No need to terminate, byte after is always '\0'. */ 88 | strncpy(process_title.str, title, process_title.len); 89 | uv__set_process_title(title); 90 | 91 | return 0; 92 | } 93 | 94 | 95 | int uv_get_process_title(char* buffer, size_t size) { 96 | if (buffer == NULL || size == 0) 97 | return -EINVAL; 98 | else if (size <= process_title.len) 99 | return -ENOBUFS; 100 | 101 | if (process_title.len != 0) 102 | memcpy(buffer, process_title.str, process_title.len + 1); 103 | 104 | buffer[process_title.len] = '\0'; 105 | 106 | return 0; 107 | } 108 | 109 | 110 | UV_DESTRUCTOR(static void free_args_mem(void)) { 111 | uv__free(args_mem); /* Keep valgrind happy. */ 112 | args_mem = NULL; 113 | } 114 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ================================ 2 | pyuv: Python interface for libuv 3 | ================================ 4 | 5 | .. image:: https://badge.fury.io/py/pyuv.png 6 | :target: http://badge.fury.io/py/pyuv 7 | 8 | pyuv is a Python module which provides an interface to libuv. 9 | `libuv `_ is a high performance 10 | asynchronous networking and platform abstraction library. 11 | 12 | libuv is built on top of epoll/kequeue/event ports/etc on Unix and 13 | IOCP on Windows systems providing a consistent API on top of them. 14 | 15 | pyuv's features: 16 | 17 | - Non-blocking TCP sockets 18 | - Non-blocking named pipes 19 | - UDP support (including multicast) 20 | - Timers 21 | - Child process spawning 22 | - Asynchronous DNS resolution (getaddrinfo) 23 | - Asynchronous file system APIs 24 | - High resolution time 25 | - System memory information 26 | - System CPUs information 27 | - Network interfaces information 28 | - Thread pool scheduling 29 | - ANSI escape code controlled TTY 30 | - File system events (inotify style and stat based) 31 | - IPC and TCP socket sharing between processes 32 | - Arbitrary file descriptor polling 33 | - Thread synchronization primitives 34 | 35 | 36 | CI status 37 | ========= 38 | 39 | Stable branch (v1.x) 40 | 41 | - Travis CI: 42 | .. image:: https://travis-ci.org/saghul/pyuv.svg?branch=v1.x 43 | :target: http://travis-ci.org/saghul/pyuv 44 | 45 | - AppVeyor: 46 | .. image:: https://ci.appveyor.com/api/projects/status/ne2un9br9t0qs5cd?svg=true 47 | :target: https://ci.appveyor.com/project/saghul/pyuv 48 | 49 | 50 | Versioning 51 | ========== 52 | 53 | Starting with version 1.0.0, pyuv follows the `Semantic Versioning `_ 54 | specification, like libuv does. 55 | 56 | All releases are downloadable from `the GitHub tags page `_, 57 | and the latest stable release from `PyPI `_. 58 | 59 | 60 | Documentation 61 | ============= 62 | 63 | http://readthedocs.org/docs/pyuv/ 64 | 65 | 66 | Installing 67 | ========== 68 | 69 | pyuv can be installed via pip as follows: 70 | 71 | :: 72 | 73 | pip install pyuv 74 | 75 | 76 | Building 77 | ======== 78 | 79 | Get the source: 80 | 81 | :: 82 | 83 | git clone https://github.com/saghul/pyuv 84 | 85 | 86 | Linux: 87 | 88 | :: 89 | 90 | ./build_inplace 91 | 92 | Mac OSX: 93 | 94 | :: 95 | 96 | (XCode needs to be installed) 97 | export ARCHFLAGS="-arch x86_64" 98 | ./build_inplace 99 | 100 | Microsoft Windows (with Visual Studio): 101 | 102 | :: 103 | 104 | python setup.py build_ext --inplace 105 | 106 | 107 | Running the test suite 108 | ====================== 109 | 110 | There are several ways of running the test ruite: 111 | 112 | - Run the test with the current Python interpreter: 113 | 114 | From the toplevel directory, run: ``nosetests -v`` 115 | 116 | - Use Tox to run the test suite in several virtualenvs with several interpreters 117 | 118 | From the toplevel directory, run: ``tox`` this will run the test suite 119 | on Python 2.7, 3.3 and 3.4 (you'll need to have them installed beforehand) 120 | 121 | 122 | Author 123 | ====== 124 | 125 | Saúl Ibarra Corretgé 126 | 127 | 128 | License 129 | ======= 130 | 131 | Unless stated otherwise on-file pyuv uses the MIT license, check LICENSE file. 132 | 133 | 134 | Python versions 135 | =============== 136 | 137 | Python 2.7, and Python >= 3.3 versions are supported. 138 | 139 | 140 | Contributing 141 | ============ 142 | 143 | If you'd like to contribute, fork the project, make a patch and send a pull 144 | request. Have a look at the surrounding code and please, make yours look 145 | alike :-) 146 | 147 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/atomic-ops.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Ben Noordhuis 2 | * 3 | * Permission to use, copy, modify, and/or distribute this software for any 4 | * purpose with or without fee is hereby granted, provided that the above 5 | * copyright notice and this permission notice appear in all copies. 6 | * 7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | */ 15 | 16 | #ifndef UV_ATOMIC_OPS_H_ 17 | #define UV_ATOMIC_OPS_H_ 18 | 19 | #include "internal.h" /* UV_UNUSED */ 20 | 21 | #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) 22 | #include 23 | #endif 24 | 25 | UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); 26 | UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)); 27 | UV_UNUSED(static void cpu_relax(void)); 28 | 29 | /* Prefer hand-rolled assembly over the gcc builtins because the latter also 30 | * issue full memory barriers. 31 | */ 32 | UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { 33 | #if defined(__i386__) || defined(__x86_64__) 34 | int out; 35 | __asm__ __volatile__ ("lock; cmpxchg %2, %1;" 36 | : "=a" (out), "+m" (*(volatile int*) ptr) 37 | : "r" (newval), "0" (oldval) 38 | : "memory"); 39 | return out; 40 | #elif defined(_AIX) && defined(__xlC__) 41 | const int out = (*(volatile int*) ptr); 42 | __compare_and_swap(ptr, &oldval, newval); 43 | return out; 44 | #elif defined(__MVS__) 45 | unsigned int op4; 46 | if (__plo_CSST(ptr, (unsigned int*) &oldval, newval, 47 | (unsigned int*) ptr, *ptr, &op4)) 48 | return oldval; 49 | else 50 | return op4; 51 | #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 52 | return atomic_cas_uint(ptr, oldval, newval); 53 | #else 54 | return __sync_val_compare_and_swap(ptr, oldval, newval); 55 | #endif 56 | } 57 | 58 | UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) { 59 | #if defined(__i386__) || defined(__x86_64__) 60 | long out; 61 | __asm__ __volatile__ ("lock; cmpxchg %2, %1;" 62 | : "=a" (out), "+m" (*(volatile long*) ptr) 63 | : "r" (newval), "0" (oldval) 64 | : "memory"); 65 | return out; 66 | #elif defined(_AIX) && defined(__xlC__) 67 | const long out = (*(volatile int*) ptr); 68 | # if defined(__64BIT__) 69 | __compare_and_swaplp(ptr, &oldval, newval); 70 | # else 71 | __compare_and_swap(ptr, &oldval, newval); 72 | # endif /* if defined(__64BIT__) */ 73 | return out; 74 | #elif defined (__MVS__) 75 | #ifdef _LP64 76 | unsigned long long op4; 77 | if (__plo_CSSTGR(ptr, (unsigned long long*) &oldval, newval, 78 | (unsigned long long*) ptr, *ptr, &op4)) 79 | #else 80 | unsigned long op4; 81 | if (__plo_CSST(ptr, (unsigned int*) &oldval, newval, 82 | (unsigned int*) ptr, *ptr, &op4)) 83 | #endif 84 | return oldval; 85 | else 86 | return op4; 87 | #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 88 | return atomic_cas_ulong(ptr, oldval, newval); 89 | #else 90 | return __sync_val_compare_and_swap(ptr, oldval, newval); 91 | #endif 92 | } 93 | 94 | UV_UNUSED(static void cpu_relax(void)) { 95 | #if defined(__i386__) || defined(__x86_64__) 96 | __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */ 97 | #endif 98 | } 99 | 100 | #endif /* UV_ATOMIC_OPS_H_ */ 101 | -------------------------------------------------------------------------------- /appveyor/run_with_env.cmd: -------------------------------------------------------------------------------- 1 | :: To build extensions for 64 bit Python 3, we need to configure environment 2 | :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: 3 | :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) 4 | :: 5 | :: To build extensions for 64 bit Python 2, we need to configure environment 6 | :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: 7 | :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) 8 | :: 9 | :: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific 10 | :: environment configurations. 11 | :: 12 | :: Note: this script needs to be run with the /E:ON and /V:ON flags for the 13 | :: cmd interpreter, at least for (SDK v7.0) 14 | :: 15 | :: More details at: 16 | :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows 17 | :: http://stackoverflow.com/a/13751649/163740 18 | :: 19 | :: Author: Olivier Grisel 20 | :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ 21 | :: 22 | :: Notes about batch files for Python people: 23 | :: 24 | :: Quotes in values are literally part of the values: 25 | :: SET FOO="bar" 26 | :: FOO is now five characters long: " b a r " 27 | :: If you don't want quotes, don't include them on the right-hand side. 28 | :: 29 | @ECHO OFF 30 | 31 | SET COMMAND_TO_RUN=%* 32 | SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows 33 | SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf 34 | 35 | :: Extract the major and minor versions, and allow for the minor version to be 36 | :: more than 9. This requires the version number to have two dots in it. 37 | SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% 38 | IF "%PYTHON_VERSION:~3,1%" == "." ( 39 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% 40 | ) ELSE ( 41 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% 42 | ) 43 | 44 | :: Based on the Python version, determine what SDK version to use, and whether 45 | :: to set the SDK for 64-bit. 46 | IF %MAJOR_PYTHON_VERSION% == 2 ( 47 | SET WINDOWS_SDK_VERSION="v7.0" 48 | SET USE_SDK=Y 49 | ) ELSE ( 50 | IF %MAJOR_PYTHON_VERSION% == 3 ( 51 | SET WINDOWS_SDK_VERSION="v7.1" 52 | IF %MINOR_PYTHON_VERSION% LEQ 4 ( 53 | SET USE_SDK=Y 54 | ) ELSE ( 55 | SET USE_SDK=N 56 | IF EXIST "%WIN_WDK%" ( 57 | :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ 58 | REN "%WIN_WDK%" 0wdf 59 | ) 60 | ) 61 | ) ELSE ( 62 | ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" 63 | EXIT 1 64 | ) 65 | ) 66 | 67 | IF %PYTHON_ARCH% == 64 ( 68 | IF %USE_SDK% == Y ( 69 | ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture 70 | SET DISTUTILS_USE_SDK=1 71 | SET MSSdk=1 72 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% 73 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release 74 | ECHO Executing: %COMMAND_TO_RUN% 75 | call %COMMAND_TO_RUN% || EXIT 1 76 | ) ELSE ( 77 | ECHO Using default MSVC build environment for 64 bit architecture 78 | ECHO Executing: %COMMAND_TO_RUN% 79 | call %COMMAND_TO_RUN% || EXIT 1 80 | ) 81 | ) ELSE ( 82 | IF %USE_SDK% == Y ( 83 | ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 32 bit architecture 84 | SET DISTUTILS_USE_SDK=1 85 | SET MSSdk=1 86 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% 87 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x86 /release 88 | ECHO Executing: %COMMAND_TO_RUN% 89 | call %COMMAND_TO_RUN% || EXIT 1 90 | ) ELSE ( 91 | ECHO Using default MSVC build environment for 32 bit architecture 92 | ECHO Executing: %COMMAND_TO_RUN% 93 | call %COMMAND_TO_RUN% || EXIT 1 94 | ) 95 | ) 96 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/poll.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { 31 | uv_poll_t* handle; 32 | int pevents; 33 | 34 | handle = container_of(w, uv_poll_t, io_watcher); 35 | 36 | if (events & POLLERR) { 37 | uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP); 38 | uv__handle_stop(handle); 39 | handle->poll_cb(handle, -EBADF, 0); 40 | return; 41 | } 42 | 43 | pevents = 0; 44 | if (events & POLLIN) 45 | pevents |= UV_READABLE; 46 | if (events & POLLOUT) 47 | pevents |= UV_WRITABLE; 48 | if (events & UV__POLLRDHUP) 49 | pevents |= UV_DISCONNECT; 50 | 51 | handle->poll_cb(handle, 0, pevents); 52 | } 53 | 54 | 55 | int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { 56 | int err; 57 | 58 | err = uv__io_check_fd(loop, fd); 59 | if (err) 60 | return err; 61 | 62 | /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL). 63 | * Workaround for e.g. kqueue fds not supporting ioctls. 64 | */ 65 | err = uv__nonblock(fd, 1); 66 | if (err == -ENOTTY) 67 | if (uv__nonblock == uv__nonblock_ioctl) 68 | err = uv__nonblock_fcntl(fd, 1); 69 | 70 | if (err) 71 | return err; 72 | 73 | uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); 74 | uv__io_init(&handle->io_watcher, uv__poll_io, fd); 75 | handle->poll_cb = NULL; 76 | return 0; 77 | } 78 | 79 | 80 | int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, 81 | uv_os_sock_t socket) { 82 | return uv_poll_init(loop, handle, socket); 83 | } 84 | 85 | 86 | static void uv__poll_stop(uv_poll_t* handle) { 87 | uv__io_stop(handle->loop, 88 | &handle->io_watcher, 89 | POLLIN | POLLOUT | UV__POLLRDHUP); 90 | uv__handle_stop(handle); 91 | } 92 | 93 | 94 | int uv_poll_stop(uv_poll_t* handle) { 95 | assert(!uv__is_closing(handle)); 96 | uv__poll_stop(handle); 97 | return 0; 98 | } 99 | 100 | 101 | int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { 102 | int events; 103 | 104 | assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0); 105 | assert(!uv__is_closing(handle)); 106 | 107 | uv__poll_stop(handle); 108 | 109 | if (pevents == 0) 110 | return 0; 111 | 112 | events = 0; 113 | if (pevents & UV_READABLE) 114 | events |= POLLIN; 115 | if (pevents & UV_WRITABLE) 116 | events |= POLLOUT; 117 | if (pevents & UV_DISCONNECT) 118 | events |= UV__POLLRDHUP; 119 | 120 | uv__io_start(handle->loop, &handle->io_watcher, events); 121 | uv__handle_start(handle); 122 | handle->poll_cb = poll_cb; 123 | 124 | return 0; 125 | } 126 | 127 | 128 | void uv__poll_close(uv_poll_t* handle) { 129 | uv__poll_stop(handle); 130 | } 131 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/getnameinfo.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "uv.h" 28 | #include "internal.h" 29 | 30 | 31 | static void uv__getnameinfo_work(struct uv__work* w) { 32 | uv_getnameinfo_t* req; 33 | int err; 34 | socklen_t salen; 35 | 36 | req = container_of(w, uv_getnameinfo_t, work_req); 37 | 38 | if (req->storage.ss_family == AF_INET) 39 | salen = sizeof(struct sockaddr_in); 40 | else if (req->storage.ss_family == AF_INET6) 41 | salen = sizeof(struct sockaddr_in6); 42 | else 43 | abort(); 44 | 45 | err = getnameinfo((struct sockaddr*) &req->storage, 46 | salen, 47 | req->host, 48 | sizeof(req->host), 49 | req->service, 50 | sizeof(req->service), 51 | req->flags); 52 | req->retcode = uv__getaddrinfo_translate_error(err); 53 | } 54 | 55 | static void uv__getnameinfo_done(struct uv__work* w, int status) { 56 | uv_getnameinfo_t* req; 57 | char* host; 58 | char* service; 59 | 60 | req = container_of(w, uv_getnameinfo_t, work_req); 61 | uv__req_unregister(req->loop, req); 62 | host = service = NULL; 63 | 64 | if (status == -ECANCELED) { 65 | assert(req->retcode == 0); 66 | req->retcode = UV_EAI_CANCELED; 67 | } else if (req->retcode == 0) { 68 | host = req->host; 69 | service = req->service; 70 | } 71 | 72 | if (req->getnameinfo_cb) 73 | req->getnameinfo_cb(req, req->retcode, host, service); 74 | } 75 | 76 | /* 77 | * Entry point for getnameinfo 78 | * return 0 if a callback will be made 79 | * return error code if validation fails 80 | */ 81 | int uv_getnameinfo(uv_loop_t* loop, 82 | uv_getnameinfo_t* req, 83 | uv_getnameinfo_cb getnameinfo_cb, 84 | const struct sockaddr* addr, 85 | int flags) { 86 | if (req == NULL || addr == NULL) 87 | return UV_EINVAL; 88 | 89 | if (addr->sa_family == AF_INET) { 90 | memcpy(&req->storage, 91 | addr, 92 | sizeof(struct sockaddr_in)); 93 | } else if (addr->sa_family == AF_INET6) { 94 | memcpy(&req->storage, 95 | addr, 96 | sizeof(struct sockaddr_in6)); 97 | } else { 98 | return UV_EINVAL; 99 | } 100 | 101 | uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO); 102 | 103 | req->getnameinfo_cb = getnameinfo_cb; 104 | req->flags = flags; 105 | req->type = UV_GETNAMEINFO; 106 | req->loop = loop; 107 | req->retcode = 0; 108 | 109 | if (getnameinfo_cb) { 110 | uv__work_submit(loop, 111 | &req->work_req, 112 | uv__getnameinfo_work, 113 | uv__getnameinfo_done); 114 | return 0; 115 | } else { 116 | uv__getnameinfo_work(&req->work_req); 117 | uv__getnameinfo_done(&req->work_req, 0); 118 | return req->retcode; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /docs/loop.rst: -------------------------------------------------------------------------------- 1 | .. _Loop: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | =============================== 8 | :py:class:`Loop` --- Event loop 9 | =============================== 10 | 11 | 12 | .. py:class:: Loop() 13 | 14 | Instantiate a new event loop. The instantiated loop is *not* the default 15 | event loop. In order to instantiate the default event loop ``default_loop`` 16 | classmethod should be used. 17 | 18 | .. py:classmethod:: default_loop 19 | 20 | Create the *default* event loop. Most applications should use this event 21 | loop if only a single loop is needed. 22 | 23 | .. py:method:: run([mode]) 24 | 25 | :param int mode: Specifies the mode in which the loop will run. 26 | It can take 3 different values: 27 | 28 | - ``UV_RUN_DEFAULT``: Default mode. Run the event loop until there are no 29 | active handles or requests. 30 | - ``UV_RUN_ONCE``: Run a single event loop iteration. 31 | - ``UV_RUN_NOWAIT``: Run a single event loop iteration, but don't block for io. 32 | 33 | Run the event loop. Returns True if there are pending operations and run should be called again 34 | or False otherwise. 35 | 36 | .. py:method:: stop 37 | 38 | Stops a running event loop. The action won't happen immediately, it will happen the next loop 39 | iteration, but if stop was called before blocking for i/o a 0 timeout poll will be performed, 40 | so the loop will not block for i/o on that iteration. 41 | 42 | .. py:method:: now 43 | .. py:method:: update_time 44 | 45 | Manage event loop time. ``now`` will return the current event loop time in 46 | milliseconds. It expresses the time when the event loop began to process 47 | events. 48 | 49 | After an operation which blocks the event loop for a long time the event loop 50 | may have lost track of time. In that case ``update_time`` should be called 51 | to query the kernel for the time. 52 | 53 | This are advanced functions not be used in standard applications. 54 | 55 | .. py:method:: queue_work(work_callback, [done_callback]) 56 | 57 | :param callable work_callback: Function that will be called in the thread pool. 58 | 59 | :param callable done_callback: Function that will be called in the caller thread after 60 | the given function has run in the thread pool. 61 | 62 | Callback signature: ``done_callback(errorno)``. Errorno indicates if the request 63 | was cancelled (UV_ECANCELLED) or None, if it was actually executed. 64 | 65 | Run the given function in a thread from the internal thread pool. A `WorkRequest` object is 66 | returned, which has a `cancel()` method that can be called to avoid running the request, in case 67 | it didn't already run. 68 | 69 | Unix only: The size of the internal threadpool can be controlled with the `UV_THREADPOOL_SIZE` 70 | environment variable, which needs to be set before the first call to this function. The default 71 | size is 4 threads. 72 | 73 | .. py:method:: excepthook(type, value, traceback) 74 | 75 | This function prints out a given traceback and exception to sys.stderr. 76 | 77 | When an exception is raised and uncaught, the interpreter calls loop.excepthook with three 78 | arguments, the exception class, exception instance, and a traceback object. The handling of 79 | such top-level exceptions can be customized by assigning another three-argument function to 80 | loop.excepthook. 81 | 82 | .. py:method:: fileno 83 | 84 | Returns the file descriptor of the polling backend. 85 | 86 | .. py:method:: get_timeout 87 | 88 | Returns the poll timeout. 89 | 90 | .. py:attribute:: handles 91 | 92 | *Read only* 93 | 94 | List of handles in this loop. 95 | 96 | .. py:attribute:: alive 97 | 98 | *Read only* 99 | 100 | Checks whether the reference count, that is, the number of active handles or requests left in the event 101 | loop is non-zero aka if the loop is currently running. 102 | 103 | -------------------------------------------------------------------------------- /deps/libuv/src/win/dl.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | static int uv__dlerror(uv_lib_t* lib, int errorno); 26 | 27 | 28 | int uv_dlopen(const char* filename, uv_lib_t* lib) { 29 | WCHAR filename_w[32768]; 30 | 31 | lib->handle = NULL; 32 | lib->errmsg = NULL; 33 | 34 | if (!MultiByteToWideChar(CP_UTF8, 35 | 0, 36 | filename, 37 | -1, 38 | filename_w, 39 | ARRAY_SIZE(filename_w))) { 40 | return uv__dlerror(lib, GetLastError()); 41 | } 42 | 43 | lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 44 | if (lib->handle == NULL) { 45 | return uv__dlerror(lib, GetLastError()); 46 | } 47 | 48 | return 0; 49 | } 50 | 51 | 52 | void uv_dlclose(uv_lib_t* lib) { 53 | if (lib->errmsg) { 54 | LocalFree((void*)lib->errmsg); 55 | lib->errmsg = NULL; 56 | } 57 | 58 | if (lib->handle) { 59 | /* Ignore errors. No good way to signal them without leaking memory. */ 60 | FreeLibrary(lib->handle); 61 | lib->handle = NULL; 62 | } 63 | } 64 | 65 | 66 | int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { 67 | *ptr = (void*) GetProcAddress(lib->handle, name); 68 | return uv__dlerror(lib, *ptr ? 0 : GetLastError()); 69 | } 70 | 71 | 72 | const char* uv_dlerror(const uv_lib_t* lib) { 73 | return lib->errmsg ? lib->errmsg : "no error"; 74 | } 75 | 76 | 77 | static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ 78 | DWORD_PTR args[1] = { (DWORD_PTR) errorno }; 79 | LPSTR fallback_error = "error: %1!d!"; 80 | 81 | FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 82 | FORMAT_MESSAGE_ARGUMENT_ARRAY | 83 | FORMAT_MESSAGE_ALLOCATE_BUFFER, 84 | fallback_error, 0, 0, 85 | (LPSTR) &lib->errmsg, 86 | 0, (va_list*) args); 87 | } 88 | 89 | 90 | 91 | static int uv__dlerror(uv_lib_t* lib, int errorno) { 92 | DWORD res; 93 | 94 | if (lib->errmsg) { 95 | LocalFree((void*)lib->errmsg); 96 | lib->errmsg = NULL; 97 | } 98 | 99 | if (errorno) { 100 | res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | 101 | FORMAT_MESSAGE_FROM_SYSTEM | 102 | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, 103 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 104 | (LPSTR) &lib->errmsg, 0, NULL); 105 | if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) { 106 | res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | 107 | FORMAT_MESSAGE_FROM_SYSTEM | 108 | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, 109 | 0, (LPSTR) &lib->errmsg, 0, NULL); 110 | } 111 | 112 | if (!res) { 113 | uv__format_fallback_error(lib, errorno); 114 | } 115 | } 116 | 117 | return errorno ? -1 : 0; 118 | } 119 | -------------------------------------------------------------------------------- /appveyor/install.ps1: -------------------------------------------------------------------------------- 1 | # Sample script to install Python and pip under Windows 2 | # Authors: Olivier Grisel, Jonathan Helmus and Kyle Kastner 3 | # License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ 4 | 5 | $MINICONDA_URL = "http://repo.continuum.io/miniconda/" 6 | $BASE_URL = "https://www.python.org/ftp/python/" 7 | $GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" 8 | $GET_PIP_PATH = "C:\get-pip.py" 9 | 10 | 11 | function Download ($filename, $url) { 12 | $webclient = New-Object System.Net.WebClient 13 | 14 | $basedir = $pwd.Path + "\" 15 | $filepath = $basedir + $filename 16 | if (Test-Path $filename) { 17 | Write-Host "Reusing" $filepath 18 | return $filepath 19 | } 20 | 21 | # Download and retry up to 3 times in case of network transient errors. 22 | Write-Host "Downloading" $filename "from" $url 23 | $retry_attempts = 2 24 | for($i=0; $i -lt $retry_attempts; $i++){ 25 | try { 26 | $webclient.DownloadFile($url, $filepath) 27 | break 28 | } 29 | Catch [Exception]{ 30 | Start-Sleep 1 31 | } 32 | } 33 | if (Test-Path $filepath) { 34 | Write-Host "File saved at" $filepath 35 | } else { 36 | # Retry once to get the error message if any at the last try 37 | $webclient.DownloadFile($url, $filepath) 38 | } 39 | return $filepath 40 | } 41 | 42 | 43 | function DownloadPython ($python_version, $platform_suffix) { 44 | $version_obj = [version]$python_version 45 | if ($version_obj -lt [version]'3.3.0' -and $version_obj.Build -eq 0) { 46 | $python_version = "$($version_obj.Major).$($version_obj.Minor)" 47 | } 48 | $filename = "python-" + $python_version + $platform_suffix + ".msi" 49 | $url = $BASE_URL + $python_version + "/" + $filename 50 | $filepath = Download $filename $url 51 | return $filepath 52 | } 53 | 54 | 55 | function InstallPython ($python_version, $architecture, $python_home) { 56 | Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home 57 | if (Test-Path $python_home) { 58 | Write-Host $python_home "already exists, skipping." 59 | return $false 60 | } 61 | if ($architecture -eq "32") { 62 | $platform_suffix = "" 63 | } else { 64 | $platform_suffix = ".amd64" 65 | } 66 | $msipath = DownloadPython $python_version $platform_suffix 67 | Write-Host "Installing" $msipath "to" $python_home 68 | $install_log = $python_home + ".log" 69 | $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home" 70 | $uninstall_args = "/qn /x $msipath" 71 | RunCommand "msiexec.exe" $install_args 72 | if (-not(Test-Path $python_home)) { 73 | Write-Host "Python seems to be installed else-where, reinstalling." 74 | RunCommand "msiexec.exe" $uninstall_args 75 | RunCommand "msiexec.exe" $install_args 76 | } 77 | if (Test-Path $python_home) { 78 | Write-Host "Python $python_version ($architecture) installation complete" 79 | } else { 80 | Write-Host "Failed to install Python in $python_home" 81 | Get-Content -Path $install_log 82 | Exit 1 83 | } 84 | } 85 | 86 | function RunCommand ($command, $command_args) { 87 | Write-Host $command $command_args 88 | Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru 89 | } 90 | 91 | 92 | function InstallPip ($python_home) { 93 | $pip_path = $python_home + "\Scripts\pip.exe" 94 | $python_path = $python_home + "\python.exe" 95 | if (-not(Test-Path $pip_path)) { 96 | Write-Host "Installing pip..." 97 | $webclient = New-Object System.Net.WebClient 98 | $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) 99 | Write-Host "Executing:" $python_path $GET_PIP_PATH 100 | Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru 101 | } else { 102 | Write-Host "pip already installed." 103 | } 104 | } 105 | 106 | 107 | function main () { 108 | InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON 109 | InstallPip $env:PYTHON 110 | } 111 | 112 | main 113 | -------------------------------------------------------------------------------- /src/error.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef PYUV_PYTHON3 3 | static PyModuleDef pyuv_error_module = { 4 | PyModuleDef_HEAD_INIT, 5 | "pyuv._cpyuv.error", /*m_name*/ 6 | NULL, /*m_doc*/ 7 | -1, /*m_size*/ 8 | NULL, /*m_methods*/ 9 | }; 10 | #endif 11 | 12 | PyObject * 13 | init_error(void) 14 | { 15 | PyObject *module; 16 | #ifdef PYUV_PYTHON3 17 | module = PyModule_Create(&pyuv_error_module); 18 | #else 19 | module = Py_InitModule("pyuv._cpyuv.error", NULL); 20 | #endif 21 | if (module == NULL) { 22 | return NULL; 23 | } 24 | 25 | PyExc_UVError = PyErr_NewException("pyuv._cpyuv.error.UVError", NULL, NULL); 26 | PyExc_ThreadError = PyErr_NewException("pyuv._cpyuv.error.ThreadError", PyExc_UVError, NULL); 27 | PyExc_HandleError = PyErr_NewException("pyuv._cpyuv.error.HandleError", PyExc_UVError, NULL); 28 | PyExc_HandleClosedError = PyErr_NewException("pyuv._cpyuv.error.HandleClosedError", PyExc_HandleError, NULL); 29 | PyExc_AsyncError = PyErr_NewException("pyuv._cpyuv.error.AsyncError", PyExc_HandleError, NULL); 30 | PyExc_TimerError = PyErr_NewException("pyuv._cpyuv.error.TimerError", PyExc_HandleError, NULL); 31 | PyExc_PrepareError = PyErr_NewException("pyuv._cpyuv.error.PrepareError", PyExc_HandleError, NULL); 32 | PyExc_IdleError = PyErr_NewException("pyuv._cpyuv.error.IdleError", PyExc_HandleError, NULL); 33 | PyExc_CheckError = PyErr_NewException("pyuv._cpyuv.error.CheckError", PyExc_HandleError, NULL); 34 | PyExc_SignalError = PyErr_NewException("pyuv._cpyuv.error.SignalError", PyExc_HandleError, NULL); 35 | PyExc_StreamError = PyErr_NewException("pyuv._cpyuv.error.StreamError", PyExc_HandleError, NULL); 36 | PyExc_TCPError = PyErr_NewException("pyuv._cpyuv.error.TCPError", PyExc_StreamError, NULL); 37 | PyExc_PipeError = PyErr_NewException("pyuv._cpyuv.error.PipeError", PyExc_StreamError, NULL); 38 | PyExc_TTYError = PyErr_NewException("pyuv._cpyuv.error.TTYError", PyExc_StreamError, NULL); 39 | PyExc_UDPError = PyErr_NewException("pyuv._cpyuv.error.UDPError", PyExc_HandleError, NULL); 40 | PyExc_PollError = PyErr_NewException("pyuv._cpyuv.error.PollError", PyExc_HandleError, NULL); 41 | PyExc_FSError = PyErr_NewException("pyuv._cpyuv.error.FSError", PyExc_UVError, NULL); 42 | PyExc_FSEventError = PyErr_NewException("pyuv._cpyuv.error.FSEventError", PyExc_HandleError, NULL); 43 | PyExc_FSPollError = PyErr_NewException("pyuv._cpyuv.error.FSPollError", PyExc_HandleError, NULL); 44 | PyExc_ProcessError = PyErr_NewException("pyuv._cpyuv.error.ProcessError", PyExc_HandleError, NULL); 45 | 46 | PyUVModule_AddType(module, "UVError", (PyTypeObject *)PyExc_UVError); 47 | PyUVModule_AddType(module, "ThreadError", (PyTypeObject *)PyExc_ThreadError); 48 | PyUVModule_AddType(module, "HandleError", (PyTypeObject *)PyExc_HandleError); 49 | PyUVModule_AddType(module, "HandleClosedError", (PyTypeObject *)PyExc_HandleClosedError); 50 | PyUVModule_AddType(module, "AsyncError", (PyTypeObject *)PyExc_AsyncError); 51 | PyUVModule_AddType(module, "TimerError", (PyTypeObject *)PyExc_TimerError); 52 | PyUVModule_AddType(module, "PrepareError", (PyTypeObject *)PyExc_PrepareError); 53 | PyUVModule_AddType(module, "IdleError", (PyTypeObject *)PyExc_IdleError); 54 | PyUVModule_AddType(module, "CheckError", (PyTypeObject *)PyExc_CheckError); 55 | PyUVModule_AddType(module, "SignalError", (PyTypeObject *)PyExc_SignalError); 56 | PyUVModule_AddType(module, "StreamError", (PyTypeObject *)PyExc_StreamError); 57 | PyUVModule_AddType(module, "TCPError", (PyTypeObject *)PyExc_TCPError); 58 | PyUVModule_AddType(module, "PipeError", (PyTypeObject *)PyExc_PipeError); 59 | PyUVModule_AddType(module, "TTYError", (PyTypeObject *)PyExc_TTYError); 60 | PyUVModule_AddType(module, "UDPError", (PyTypeObject *)PyExc_UDPError); 61 | PyUVModule_AddType(module, "PollError", (PyTypeObject *)PyExc_PollError); 62 | PyUVModule_AddType(module, "FSError", (PyTypeObject *)PyExc_FSError); 63 | PyUVModule_AddType(module, "FSEventError", (PyTypeObject *)PyExc_FSEventError); 64 | PyUVModule_AddType(module, "FSPollError", (PyTypeObject *)PyExc_FSPollError); 65 | PyUVModule_AddType(module, "ProcessError", (PyTypeObject *)PyExc_ProcessError); 66 | 67 | return module; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /docs/process.rst: -------------------------------------------------------------------------------- 1 | .. _process: 2 | 3 | 4 | .. currentmodule:: pyuv 5 | 6 | 7 | ===================================================== 8 | :py:class:`Process` --- Child process spawning handle 9 | ===================================================== 10 | 11 | 12 | ``Process`` handles allow spawning child processes which can be controlled (their stdin and 13 | stdout) with ``Pipe`` handles within an event loop. 14 | 15 | 16 | .. py:classmethod:: disable_stdio_inheritance 17 | 18 | Disables inheritance for file descriptors / handles that this process 19 | inherited from its parent. The effect is that child processes spawned by 20 | this process don't accidentally inherit these handles. 21 | 22 | It is recommended to call this function as early in your program as possible, 23 | before the inherited file descriptors can be closed or duplicated. 24 | 25 | Note that this function works on a best-effort basis: there is no guarantee 26 | that libuv can discover all file descriptors that were inherited. In general 27 | it does a better job on Windows than it does on unix. 28 | 29 | .. py:classmethod:: spawn(loop, args, [executable, [env, [cwd, [uid, [gid, [flags, [stdio, [exit_callback]]]]]]]]) 30 | 31 | :param: Loop loop: `pyuv.Loop` instance where this handle belongs. 32 | 33 | :param list args: Arguments for the new process. In case it's just the executable, it's 34 | possible to specify it as a string instead of a single element list. 35 | 36 | :param string executable: File to be executed. args[0] is taken in case it's not specified. 37 | 38 | :param callable exit_callback: Callback to be called when the process exits. 39 | 40 | :param dict env: Overrides the environment for the child process. If none is 41 | specified the one from the parent is used. 42 | 43 | :param string cwd: Specifies the working directory where the child process will 44 | be executed. 45 | 46 | :param int uid: UID of the user to be used if flag ``UV_PROCESS_SETUID`` is used. 47 | 48 | :param int gid: GID of the group to be used if flag ``UV_PROCESS_SETGID`` is used. 49 | 50 | :param int flags: Available flags: 51 | 52 | - ``UV_PROCESS_SETUID``: set child UID 53 | - ``UV_PROCESS_SETGID``: set child GID 54 | - ``UV_PROCESS_WINDOWS_HIDE``: hide the subprocess console window that would normally be created. 55 | This option is only meaningful on Windows systems. On unix it is silently ignored. 56 | - ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS``: pass arguments verbatim, that is, not enclosed 57 | in double quotes (Windows) 58 | - ``UV_PROCESS_DETACHED``: detach child process from parent 59 | 60 | :param list stdio: Sequence containing ``StdIO`` containers which will be used to pass stdio 61 | handles to the child process. See the ``StdIO`` class documentation for for information. 62 | 63 | Spawn the specified child process. 64 | 65 | Exit callback signature: ``callback(process_handle, exit_status, term_signal)``. 66 | 67 | .. py:method:: kill(signal) 68 | 69 | :param int signal: Signal to be sent to the process. 70 | 71 | Send the specified signal to the child process. 72 | 73 | .. py:attribute:: pid 74 | 75 | *Read only* 76 | 77 | PID of the spawned process. 78 | 79 | 80 | .. py:class:: StdIO([[[stream], fd], flags]) 81 | 82 | :param object stream: Stream object. 83 | 84 | :param int fd: File descriptor. 85 | 86 | :param int flags: Flags. 87 | 88 | Create a new container for passing stdio to a child process. Stream can be any stream object, 89 | that is ``TCP``, ``Pipe`` or ``TTY``. An arbitrary file descriptor can be passed by setting 90 | the ``fd`` parameter. 91 | 92 | The operation mode is selected by setting the ``flags`` parameter: 93 | 94 | - UV_IGNORE: this container should be ignored. 95 | - UV_CREATE_PIPE: indicates a pipe should be created. UV_READABLE_PIPE and UV_WRITABLE_PIPE determine the direction of flow, from the child process' perspective. Both flags may be specified to create a duplex data stream. 96 | - UV_INHERIT_FD: inherit the given file descriptor in the child. 97 | - UV_INHERIT_STREAM: inherit the file descriptor of the given stream in the child. 98 | 99 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/loop-watcher.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #define UV_LOOP_WATCHER_DEFINE(name, type) \ 26 | int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ 27 | uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \ 28 | handle->name##_cb = NULL; \ 29 | return 0; \ 30 | } \ 31 | \ 32 | int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ 33 | if (uv__is_active(handle)) return 0; \ 34 | if (cb == NULL) return -EINVAL; \ 35 | QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue); \ 36 | handle->name##_cb = cb; \ 37 | uv__handle_start(handle); \ 38 | return 0; \ 39 | } \ 40 | \ 41 | int uv_##name##_stop(uv_##name##_t* handle) { \ 42 | if (!uv__is_active(handle)) return 0; \ 43 | QUEUE_REMOVE(&handle->queue); \ 44 | uv__handle_stop(handle); \ 45 | return 0; \ 46 | } \ 47 | \ 48 | void uv__run_##name(uv_loop_t* loop) { \ 49 | uv_##name##_t* h; \ 50 | QUEUE queue; \ 51 | QUEUE* q; \ 52 | QUEUE_MOVE(&loop->name##_handles, &queue); \ 53 | while (!QUEUE_EMPTY(&queue)) { \ 54 | q = QUEUE_HEAD(&queue); \ 55 | h = QUEUE_DATA(q, uv_##name##_t, queue); \ 56 | QUEUE_REMOVE(q); \ 57 | QUEUE_INSERT_TAIL(&loop->name##_handles, q); \ 58 | h->name##_cb(h); \ 59 | } \ 60 | } \ 61 | \ 62 | void uv__##name##_close(uv_##name##_t* handle) { \ 63 | uv_##name##_stop(handle); \ 64 | } 65 | 66 | UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) 67 | UV_LOOP_WATCHER_DEFINE(check, CHECK) 68 | UV_LOOP_WATCHER_DEFINE(idle, IDLE) 69 | -------------------------------------------------------------------------------- /deps/libuv/src/unix/bsd-ifaddrs.c: -------------------------------------------------------------------------------- 1 | /* Copyright libuv project contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include "uv.h" 23 | #include "internal.h" 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #if !defined(__CYGWIN__) && !defined(__MSYS__) 31 | #include 32 | #endif 33 | 34 | static int uv__ifaddr_exclude(struct ifaddrs *ent) { 35 | if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) 36 | return 1; 37 | if (ent->ifa_addr == NULL) 38 | return 1; 39 | #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) 40 | /* 41 | * On BSD getifaddrs returns information related to the raw underlying 42 | * devices. We're not interested in this information. 43 | */ 44 | if (ent->ifa_addr->sa_family == AF_LINK) 45 | return 1; 46 | #elif defined(__NetBSD__) || defined(__OpenBSD__) 47 | if (ent->ifa_addr->sa_family != PF_INET) 48 | return 1; 49 | #endif 50 | return 0; 51 | } 52 | 53 | int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { 54 | struct ifaddrs* addrs; 55 | struct ifaddrs* ent; 56 | uv_interface_address_t* address; 57 | int i; 58 | 59 | if (getifaddrs(&addrs) != 0) 60 | return -errno; 61 | 62 | *count = 0; 63 | 64 | /* Count the number of interfaces */ 65 | for (ent = addrs; ent != NULL; ent = ent->ifa_next) { 66 | if (uv__ifaddr_exclude(ent)) 67 | continue; 68 | (*count)++; 69 | } 70 | 71 | *addresses = uv__malloc(*count * sizeof(**addresses)); 72 | 73 | if (*addresses == NULL) { 74 | freeifaddrs(addrs); 75 | return -ENOMEM; 76 | } 77 | 78 | address = *addresses; 79 | 80 | for (ent = addrs; ent != NULL; ent = ent->ifa_next) { 81 | if (uv__ifaddr_exclude(ent)) 82 | continue; 83 | 84 | address->name = uv__strdup(ent->ifa_name); 85 | 86 | if (ent->ifa_addr->sa_family == AF_INET6) { 87 | address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); 88 | } else { 89 | address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); 90 | } 91 | 92 | if (ent->ifa_netmask->sa_family == AF_INET6) { 93 | address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); 94 | } else { 95 | address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); 96 | } 97 | 98 | address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); 99 | 100 | address++; 101 | } 102 | 103 | /* Fill in physical addresses for each interface */ 104 | for (ent = addrs; ent != NULL; ent = ent->ifa_next) { 105 | if (uv__ifaddr_exclude(ent)) 106 | continue; 107 | 108 | address = *addresses; 109 | 110 | for (i = 0; i < *count; i++) { 111 | if (strcmp(address->name, ent->ifa_name) == 0) { 112 | #if defined(__CYGWIN__) || defined(__MSYS__) 113 | memset(address->phys_addr, 0, sizeof(address->phys_addr)); 114 | #else 115 | struct sockaddr_dl* sa_addr; 116 | sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); 117 | memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); 118 | #endif 119 | } 120 | address++; 121 | } 122 | } 123 | 124 | freeifaddrs(addrs); 125 | 126 | return 0; 127 | } 128 | 129 | 130 | void uv_free_interface_addresses(uv_interface_address_t* addresses, 131 | int count) { 132 | int i; 133 | 134 | for (i = 0; i < count; i++) { 135 | uv__free(addresses[i].name); 136 | } 137 | 138 | uv__free(addresses); 139 | } 140 | -------------------------------------------------------------------------------- /deps/libuv/src/win/handle.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "uv.h" 27 | #include "internal.h" 28 | #include "handle-inl.h" 29 | 30 | 31 | uv_handle_type uv_guess_handle(uv_file file) { 32 | HANDLE handle; 33 | DWORD mode; 34 | 35 | if (file < 0) { 36 | return UV_UNKNOWN_HANDLE; 37 | } 38 | 39 | handle = uv__get_osfhandle(file); 40 | 41 | switch (GetFileType(handle)) { 42 | case FILE_TYPE_CHAR: 43 | if (GetConsoleMode(handle, &mode)) { 44 | return UV_TTY; 45 | } else { 46 | return UV_FILE; 47 | } 48 | 49 | case FILE_TYPE_PIPE: 50 | return UV_NAMED_PIPE; 51 | 52 | case FILE_TYPE_DISK: 53 | return UV_FILE; 54 | 55 | default: 56 | return UV_UNKNOWN_HANDLE; 57 | } 58 | } 59 | 60 | 61 | int uv_is_active(const uv_handle_t* handle) { 62 | return (handle->flags & UV__HANDLE_ACTIVE) && 63 | !(handle->flags & UV__HANDLE_CLOSING); 64 | } 65 | 66 | 67 | void uv_close(uv_handle_t* handle, uv_close_cb cb) { 68 | uv_loop_t* loop = handle->loop; 69 | 70 | if (handle->flags & UV__HANDLE_CLOSING) { 71 | assert(0); 72 | return; 73 | } 74 | 75 | handle->close_cb = cb; 76 | 77 | /* Handle-specific close actions */ 78 | switch (handle->type) { 79 | case UV_TCP: 80 | uv_tcp_close(loop, (uv_tcp_t*)handle); 81 | return; 82 | 83 | case UV_NAMED_PIPE: 84 | uv_pipe_close(loop, (uv_pipe_t*) handle); 85 | return; 86 | 87 | case UV_TTY: 88 | uv_tty_close((uv_tty_t*) handle); 89 | return; 90 | 91 | case UV_UDP: 92 | uv_udp_close(loop, (uv_udp_t*) handle); 93 | return; 94 | 95 | case UV_POLL: 96 | uv_poll_close(loop, (uv_poll_t*) handle); 97 | return; 98 | 99 | case UV_TIMER: 100 | uv_timer_stop((uv_timer_t*)handle); 101 | uv__handle_closing(handle); 102 | uv_want_endgame(loop, handle); 103 | return; 104 | 105 | case UV_PREPARE: 106 | uv_prepare_stop((uv_prepare_t*)handle); 107 | uv__handle_closing(handle); 108 | uv_want_endgame(loop, handle); 109 | return; 110 | 111 | case UV_CHECK: 112 | uv_check_stop((uv_check_t*)handle); 113 | uv__handle_closing(handle); 114 | uv_want_endgame(loop, handle); 115 | return; 116 | 117 | case UV_IDLE: 118 | uv_idle_stop((uv_idle_t*)handle); 119 | uv__handle_closing(handle); 120 | uv_want_endgame(loop, handle); 121 | return; 122 | 123 | case UV_ASYNC: 124 | uv_async_close(loop, (uv_async_t*) handle); 125 | return; 126 | 127 | case UV_SIGNAL: 128 | uv_signal_close(loop, (uv_signal_t*) handle); 129 | return; 130 | 131 | case UV_PROCESS: 132 | uv_process_close(loop, (uv_process_t*) handle); 133 | return; 134 | 135 | case UV_FS_EVENT: 136 | uv_fs_event_close(loop, (uv_fs_event_t*) handle); 137 | return; 138 | 139 | case UV_FS_POLL: 140 | uv__fs_poll_close((uv_fs_poll_t*) handle); 141 | uv__handle_closing(handle); 142 | uv_want_endgame(loop, handle); 143 | return; 144 | 145 | default: 146 | /* Not supported */ 147 | abort(); 148 | } 149 | } 150 | 151 | 152 | int uv_is_closing(const uv_handle_t* handle) { 153 | return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); 154 | } 155 | 156 | 157 | uv_os_fd_t uv_get_osfhandle(int fd) { 158 | return uv__get_osfhandle(fd); 159 | } 160 | -------------------------------------------------------------------------------- /deps/libuv/src/win/getnameinfo.c: -------------------------------------------------------------------------------- 1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to 5 | * deal in the Software without restriction, including without limitation the 6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | * sell copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | * IN THE SOFTWARE. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "uv.h" 26 | #include "internal.h" 27 | #include "req-inl.h" 28 | 29 | #ifndef GetNameInfo 30 | int WSAAPI GetNameInfoW( 31 | const SOCKADDR *pSockaddr, 32 | socklen_t SockaddrLength, 33 | PWCHAR pNodeBuffer, 34 | DWORD NodeBufferSize, 35 | PWCHAR pServiceBuffer, 36 | DWORD ServiceBufferSize, 37 | INT Flags 38 | ); 39 | #endif 40 | 41 | static void uv__getnameinfo_work(struct uv__work* w) { 42 | uv_getnameinfo_t* req; 43 | WCHAR host[NI_MAXHOST]; 44 | WCHAR service[NI_MAXSERV]; 45 | int ret = 0; 46 | 47 | req = container_of(w, uv_getnameinfo_t, work_req); 48 | if (GetNameInfoW((struct sockaddr*)&req->storage, 49 | sizeof(req->storage), 50 | host, 51 | ARRAY_SIZE(host), 52 | service, 53 | ARRAY_SIZE(service), 54 | req->flags)) { 55 | ret = WSAGetLastError(); 56 | } 57 | req->retcode = uv__getaddrinfo_translate_error(ret); 58 | 59 | /* convert results to UTF-8 */ 60 | WideCharToMultiByte(CP_UTF8, 61 | 0, 62 | host, 63 | -1, 64 | req->host, 65 | sizeof(req->host), 66 | NULL, 67 | NULL); 68 | 69 | WideCharToMultiByte(CP_UTF8, 70 | 0, 71 | service, 72 | -1, 73 | req->service, 74 | sizeof(req->service), 75 | NULL, 76 | NULL); 77 | } 78 | 79 | 80 | /* 81 | * Called from uv_run when complete. 82 | */ 83 | static void uv__getnameinfo_done(struct uv__work* w, int status) { 84 | uv_getnameinfo_t* req; 85 | char* host; 86 | char* service; 87 | 88 | req = container_of(w, uv_getnameinfo_t, work_req); 89 | uv__req_unregister(req->loop, req); 90 | host = service = NULL; 91 | 92 | if (status == UV_ECANCELED) { 93 | assert(req->retcode == 0); 94 | req->retcode = UV_EAI_CANCELED; 95 | } else if (req->retcode == 0) { 96 | host = req->host; 97 | service = req->service; 98 | } 99 | 100 | if (req->getnameinfo_cb) 101 | req->getnameinfo_cb(req, req->retcode, host, service); 102 | } 103 | 104 | 105 | /* 106 | * Entry point for getnameinfo 107 | * return 0 if a callback will be made 108 | * return error code if validation fails 109 | */ 110 | int uv_getnameinfo(uv_loop_t* loop, 111 | uv_getnameinfo_t* req, 112 | uv_getnameinfo_cb getnameinfo_cb, 113 | const struct sockaddr* addr, 114 | int flags) { 115 | if (req == NULL || addr == NULL) 116 | return UV_EINVAL; 117 | 118 | if (addr->sa_family == AF_INET) { 119 | memcpy(&req->storage, 120 | addr, 121 | sizeof(struct sockaddr_in)); 122 | } else if (addr->sa_family == AF_INET6) { 123 | memcpy(&req->storage, 124 | addr, 125 | sizeof(struct sockaddr_in6)); 126 | } else { 127 | return UV_EINVAL; 128 | } 129 | 130 | UV_REQ_INIT(req, UV_GETNAMEINFO); 131 | uv__req_register(loop, req); 132 | 133 | req->getnameinfo_cb = getnameinfo_cb; 134 | req->flags = flags; 135 | req->loop = loop; 136 | req->retcode = 0; 137 | 138 | if (getnameinfo_cb) { 139 | uv__work_submit(loop, 140 | &req->work_req, 141 | uv__getnameinfo_work, 142 | uv__getnameinfo_done); 143 | return 0; 144 | } else { 145 | uv__getnameinfo_work(&req->work_req); 146 | uv__getnameinfo_done(&req->work_req, 0); 147 | return req->retcode; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/abstract.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | uv_timer_t timer; 8 | Pipe *pipe; 9 | PyObject *callback; 10 | } abstract_connect_req; 11 | 12 | 13 | static void 14 | pyuv__deallocate_handle_data(uv_handle_t *handle) 15 | { 16 | PyMem_Free(handle->data); 17 | } 18 | 19 | 20 | static void 21 | pyuv__pipe_connect_abstract_cb(uv_timer_t *timer) 22 | { 23 | PyGILState_STATE gstate = PyGILState_Ensure(); 24 | PyObject *result, *error; 25 | abstract_connect_req *req; 26 | 27 | ASSERT(timer != NULL); 28 | req = (abstract_connect_req *) timer->data; 29 | 30 | error = Py_None; 31 | Py_INCREF(error); 32 | 33 | result = PyObject_CallFunctionObjArgs(req->callback, req->pipe, error, NULL); 34 | if (result == NULL) { 35 | handle_uncaught_exception(HANDLE(req->pipe)->loop); 36 | } 37 | 38 | Py_XDECREF(result); 39 | Py_DECREF(error); 40 | 41 | Py_DECREF(req->callback); 42 | Py_DECREF(req->pipe); 43 | 44 | uv_close((uv_handle_t *) &req->timer, pyuv__deallocate_handle_data); 45 | 46 | PyGILState_Release(gstate); 47 | } 48 | 49 | 50 | static PyObject * 51 | Pipe_func_bind_abstract(Pipe *self, const char *name, int len) 52 | { 53 | int fd = -1, err; 54 | struct sockaddr_un saddr; 55 | 56 | err = socket(AF_UNIX, SOCK_STREAM, 0); 57 | if (err < 0) { 58 | RAISE_UV_EXCEPTION(-errno, PyExc_PipeError); 59 | goto error; 60 | } 61 | fd = err; 62 | 63 | /* Clip overly long paths, mimics libuv behavior. */ 64 | 65 | memset(&saddr, 0, sizeof(saddr)); 66 | saddr.sun_family = AF_UNIX; 67 | if (len >= (int) sizeof(saddr.sun_path)) 68 | len = sizeof(saddr.sun_path) - 1; 69 | memcpy(saddr.sun_path, name, len); 70 | 71 | err = bind(fd, (struct sockaddr *) &saddr, sizeof(saddr.sun_family) + len); 72 | if (err < 0) { 73 | RAISE_UV_EXCEPTION(-errno, PyExc_PipeError); 74 | goto error; 75 | } 76 | 77 | /* uv_pipe_open() puts the fd in non-blocking mode so no need to do that 78 | * ourselves. */ 79 | 80 | err = uv_pipe_open(&self->pipe_h, fd); 81 | if (err < 0) { 82 | RAISE_UV_EXCEPTION(err, PyExc_PipeError); 83 | goto error; 84 | } 85 | 86 | Py_INCREF(Py_None); 87 | return Py_None; 88 | 89 | error: 90 | if (fd != -1) 91 | close(fd); 92 | 93 | return NULL; 94 | } 95 | 96 | 97 | static PyObject * 98 | Pipe_func_connect_abstract(Pipe *self, const char *name, int len, PyObject *callback) 99 | { 100 | int fd = -1, err; 101 | struct sockaddr_un saddr; 102 | abstract_connect_req *req = NULL; 103 | 104 | err = socket(AF_UNIX, SOCK_STREAM, 0); 105 | if (err < 0) { 106 | RAISE_UV_EXCEPTION(-errno, PyExc_PipeError); 107 | goto error; 108 | } 109 | fd = err; 110 | 111 | /* This is a local (AF_UNIX) socket and connect() on Linux is not 112 | * supposed to block as far as I can tell. And even if it would block for a 113 | * very small amount of time that would be OK. */ 114 | 115 | if (len >= (int) sizeof(saddr.sun_path)) 116 | len = sizeof(saddr.sun_path) - 1; 117 | saddr.sun_family = AF_UNIX; 118 | memset(saddr.sun_path, 0, sizeof(saddr.sun_path)); 119 | memcpy(saddr.sun_path, name, len); 120 | saddr.sun_path[len] = '\0'; 121 | 122 | err = connect(fd, (struct sockaddr *) &saddr, sizeof(saddr.sun_family) + len); 123 | if (err < 0) { 124 | RAISE_UV_EXCEPTION(-errno, PyExc_PipeError); 125 | goto error; 126 | } 127 | 128 | err = uv_pipe_open(&self->pipe_h, fd); 129 | if (err < 0) { 130 | RAISE_UV_EXCEPTION(err, PyExc_PipeError); 131 | goto error; 132 | } 133 | fd = -1; 134 | 135 | /* Now we need to fire the callback. We can't just call it here as it's 136 | * expected to be fired from the event loop. Use a zero-timeout uv_timer to 137 | * schedule it for the next loop iteration. */ 138 | 139 | req = PyMem_Malloc(sizeof(abstract_connect_req)); 140 | if (req == NULL) { 141 | PyErr_NoMemory(); 142 | goto error; 143 | } 144 | 145 | err = uv_timer_init(UV_HANDLE_LOOP(self), &req->timer); 146 | if (err < 0) { 147 | RAISE_UV_EXCEPTION(err, PyExc_PipeError); 148 | goto error; 149 | } 150 | req->pipe = self; 151 | req->callback = callback; 152 | req->timer.data = req; 153 | 154 | Py_INCREF(req->pipe); 155 | Py_INCREF(req->callback); 156 | 157 | err = uv_timer_start(&req->timer, pyuv__pipe_connect_abstract_cb, 0, 0); 158 | if (err < 0) { 159 | RAISE_UV_EXCEPTION(err, PyExc_PipeError); 160 | goto error; 161 | } 162 | 163 | Py_INCREF(Py_None); 164 | return Py_None; 165 | 166 | error: 167 | if (fd != -1) 168 | close(fd); 169 | if (req != NULL) 170 | PyMem_Free(req); 171 | 172 | return NULL; 173 | } 174 | --------------------------------------------------------------------------------