Blame docs/src/migration_010_100.rst

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