Blame docs/src/migration_010_100.rst

Packit Service 7c31a4
Packit Service 7c31a4
.. _migration_010_100:
Packit Service 7c31a4
Packit Service 7c31a4
libuv 0.10 -> 1.0.0 migration guide
Packit Service 7c31a4
===================================
Packit Service 7c31a4
Packit Service 7c31a4
Some APIs changed quite a bit throughout the 1.0.0 development process. Here
Packit Service 7c31a4
is a migration guide for the most significant changes that happened after 0.10
Packit Service 7c31a4
was released.
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Loop initialization and closing
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 0.10 (and previous versions), loops were created with `uv_loop_new`, which
Packit Service 7c31a4
allocated memory for a new loop and initialized it; and destroyed with `uv_loop_delete`,
Packit Service 7c31a4
which destroyed the loop and freed the memory. Starting with 1.0, those are deprecated
Packit Service 7c31a4
and the user is responsible for allocating the memory and then initializing the loop.
Packit Service 7c31a4
Packit Service 7c31a4
libuv 0.10
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    uv_loop_t* loop = uv_loop_new();
Packit Service 7c31a4
    ...
Packit Service 7c31a4
    uv_loop_delete(loop);
Packit Service 7c31a4
Packit Service 7c31a4
libuv 1.0
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    uv_loop_t* loop = malloc(sizeof *loop);
Packit Service 7c31a4
    uv_loop_init(loop);
Packit Service 7c31a4
    ...
Packit Service 7c31a4
    uv_loop_close(loop);
Packit Service 7c31a4
    free(loop);
Packit Service 7c31a4
Packit Service 7c31a4
.. note::
Packit Service 7c31a4
    Error handling was omitted for brevity. Check the documentation for :c:func:`uv_loop_init`
Packit Service 7c31a4
    and :c:func:`uv_loop_close`.
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Error handling
Packit Service 7c31a4
~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
Error handling had a major overhaul in libuv 1.0. In general, functions and status parameters
Packit Service 7c31a4
would get 0 for success and -1 for failure on libuv 0.10, and the user had to use `uv_last_error`
Packit Service 7c31a4
to fetch the error code, which was a positive number.
Packit Service 7c31a4
Packit Service 7c31a4
In 1.0, functions and status parameters contain the actual error code, which is 0 for success, or
Packit Service 7c31a4
a negative number in case of error.
Packit Service 7c31a4
Packit Service 7c31a4
libuv 0.10
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    ... assume 'server' is a TCP server which is already listening
Packit Service 7c31a4
    r = uv_listen((uv_stream_t*) server, 511, NULL);
Packit Service 7c31a4
    if (r == -1) {
Packit Service 7c31a4
      uv_err_t err = uv_last_error(uv_default_loop());
Packit Service 7c31a4
      /* err.code contains UV_EADDRINUSE */
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
libuv 1.0
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    ... assume 'server' is a TCP server which is already listening
Packit Service 7c31a4
    r = uv_listen((uv_stream_t*) server, 511, NULL);
Packit Service 7c31a4
    if (r < 0) {
Packit Service 7c31a4
      /* r contains UV_EADDRINUSE */
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Threadpool changes
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 0.10 Unix used a threadpool which defaulted to 4 threads, while Windows used the
Packit Service 7c31a4
`QueueUserWorkItem` API, which uses a Windows internal threadpool, which defaults to 512
Packit Service 7c31a4
threads per process.
Packit Service 7c31a4
Packit Service 7c31a4
In 1.0, we unified both implementations, so Windows now uses the same implementation Unix
Packit Service 7c31a4
does. The threadpool size can be set by exporting the ``UV_THREADPOOL_SIZE`` environment
Packit Service 7c31a4
variable. See :c:ref:`threadpool`.
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Allocation callback API change
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 0.10 the callback had to return a filled :c:type:`uv_buf_t` by value:
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
Packit Service 7c31a4
        return uv_buf_init(malloc(size), size);
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 1.0 a pointer to a buffer is passed to the callback, which the user
Packit Service 7c31a4
needs to fill:
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
Packit Service 7c31a4
        buf->base = malloc(size);
Packit Service 7c31a4
        buf->len = size;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Unification of IPv4 / IPv6 APIs
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
libuv 1.0 unified the IPv4 and IPv6 APIS. There is no longer a `uv_tcp_bind` and `uv_tcp_bind6`
Packit Service 7c31a4
duality, there is only :c:func:`uv_tcp_bind` now.
Packit Service 7c31a4
Packit Service 7c31a4
IPv4 functions took ``struct sockaddr_in`` structures by value, and IPv6 functions took
Packit Service 7c31a4
``struct sockaddr_in6``. Now functions take a ``struct sockaddr*`` (note it's a pointer).
Packit Service 7c31a4
It can be stack allocated.
Packit Service 7c31a4
Packit Service 7c31a4
libuv 0.10
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", 1234);
Packit Service 7c31a4
    ...
Packit Service 7c31a4
    uv_tcp_bind(&server, addr)
Packit Service 7c31a4
Packit Service 7c31a4
libuv 1.0
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    struct sockaddr_in addr;
Packit Service 7c31a4
    uv_ip4_addr("0.0.0.0", 1234, &addr)
Packit Service 7c31a4
    ...
Packit Service 7c31a4
    uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
Packit Service 7c31a4
Packit Service 7c31a4
The IPv4 and IPv6 struct creating functions (:c:func:`uv_ip4_addr` and :c:func:`uv_ip6_addr`)
Packit Service 7c31a4
have also changed, make sure you check the documentation.
Packit Service 7c31a4
Packit Service 7c31a4
..note::
Packit Service 7c31a4
    This change applies to all functions that made a distinction between IPv4 and IPv6
Packit Service 7c31a4
    addresses.
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Streams / UDP  data receive callback API change
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
The streams and UDP data receive callbacks now get a pointer to a :c:type:`uv_buf_t` buffer,
Packit Service 7c31a4
not a structure by value.
Packit Service 7c31a4
Packit Service 7c31a4
libuv 0.10
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    void on_read(uv_stream_t* handle,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 uv_buf_t buf) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    void recv_cb(uv_udp_t* handle,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 uv_buf_t buf,
Packit Service 7c31a4
                 struct sockaddr* addr,
Packit Service 7c31a4
                 unsigned flags) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
libuv 1.0
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    void on_read(uv_stream_t* handle,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 const uv_buf_t* buf) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    void recv_cb(uv_udp_t* handle,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 const uv_buf_t* buf,
Packit Service 7c31a4
                 const struct sockaddr* addr,
Packit Service 7c31a4
                 unsigned flags) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Receiving handles over pipes API change
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 0.10 (and earlier versions) the `uv_read2_start` function was used to start reading
Packit Service 7c31a4
data on a pipe, which could also result in the reception of handles over it. The callback
Packit Service 7c31a4
for such function looked like this:
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    void on_read(uv_pipe_t* pipe,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 uv_buf_t buf,
Packit Service 7c31a4
                 uv_handle_type pending) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
In libuv 1.0, `uv_read2_start` was removed, and the user needs to check if there are pending
Packit Service 7c31a4
handles using :c:func:`uv_pipe_pending_count` and :c:func:`uv_pipe_pending_type` while in
Packit Service 7c31a4
the read callback:
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    void on_read(uv_stream_t* handle,
Packit Service 7c31a4
                 ssize_t nread,
Packit Service 7c31a4
                 const uv_buf_t* buf) {
Packit Service 7c31a4
        ...
Packit Service 7c31a4
        while (uv_pipe_pending_count((uv_pipe_t*) handle) != 0) {
Packit Service 7c31a4
            pending = uv_pipe_pending_type((uv_pipe_t*) handle);
Packit Service 7c31a4
            ...
Packit Service 7c31a4
        }
Packit Service 7c31a4
        ...
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
Extracting the file descriptor out of a handle
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
While it wasn't supported by the API, users often accessed the libuv internals in
Packit Service 7c31a4
order to get access to the file descriptor of a TCP handle, for example.
Packit Service 7c31a4
Packit Service 7c31a4
::
Packit Service 7c31a4
Packit Service 7c31a4
    fd = handle->io_watcher.fd;
Packit Service 7c31a4
Packit Service 7c31a4
This is now properly exposed through the :c:func:`uv_fileno` function.
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uv_fs_readdir rename and API change
Packit Service 7c31a4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit Service 7c31a4
Packit Service 7c31a4
`uv_fs_readdir` returned a list of strings in the `req->ptr` field upon completion in
Packit Service 7c31a4
libuv 0.10. In 1.0, this function got renamed to :c:func:`uv_fs_scandir`, since it's
Packit Service 7c31a4
actually implemented using ``scandir(3)``.
Packit Service 7c31a4
Packit Service 7c31a4
In addition, instead of allocating a full list strings, the user is able to get one
Packit Service 7c31a4
result at a time by using the :c:func:`uv_fs_scandir_next` function. This function
Packit Service 7c31a4
does not need to make a roundtrip to the threadpool, because libuv will keep the
Packit Service 7c31a4
list of *dents* returned by ``scandir(3)`` around.