Skip to content

zelang-dev/uv_coroutine

Repository files navigation

uv_coroutine

windows & linux & macOSmacOSarmv7, aarch64, ppc64leriscv64 & s390x by ucontext  .

Table of Contents

Introduction

This library provides ease of use convenience wrappers for libuv combined with the power of c-raii, a high level memory management library similar to other languages, among other features. Like coroutine support, the otherwise callback needed, is now automatically back to the caller with results.

  • All functions requiring allocation and passing pointers, now returns them instead, if needed.
  • The general naming convention is to drop uv_ prefix and require only necessary arguments/options.
  • This integration also requires the use of uv_main(int argc, char **argv) as the startup entry routine:

libuv example from https://github.com/libuv/libuv/tree/master/docs/code/

helloworld.c helloworld/main.c
#include "uv_coro.h"

int uv_main(int argc, char **argv) {
    printf("Now quitting.\n");
    yielding();

    return coro_err_code();
}
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main() {
    uv_loop_t *loop = malloc(sizeof(uv_loop_t));
    uv_loop_init(loop);

    printf("Now quitting.\n");
    uv_run(loop, UV_RUN_DEFAULT);

    uv_loop_close(loop);
    free(loop);
    return 0;
}

This general means there will be a dramatic reduction of lines of code repeated, repeatedly.

Libuv guides/examples:

Reduced to:

uvcat.c - 13 lines uvtee.c - 20 lines
#include "uv_coro.h"

int uv_main(int argc, char **argv) {
    uv_file fd = fs_open(argv[1], O_RDONLY, 0);
    if (fd > 0) {
        string text = fs_read(fd, -1);
        fs_write(STDOUT_FILENO, text, -1);

        return fs_close(fd);
    }

    return fd;
}
#include "uv_coro.h"

int uv_main(int argc, char **argv) {
    string text = nullptr;
    uv_file fd = fs_open(argv[1], O_CREAT | O_RDWR, 0644);
    if (fd > 0) {
        pipe_file_t *file_pipe = pipe_file(fd, false);
        pipe_out_t *stdout_pipe = pipe_stdout(false);
        pipe_in_t *stdin_pipe = pipe_stdin(false);
        while (text = stream_read(stdin_pipe->reader)) {
            if (stream_write(stdout_pipe->writer, text)
                || stream_write(file_pipe->handle, text))
                break;
        }

        return fs_close(fd);
    }

    return fd;
}
tcp-echo-server.c - 27 lines
#include "uv_coro.h"

#define DEFAULT_PORT 7000
#define DEFAULT_BACKLOG 128

void new_connection(uv_stream_t *socket) {
    string data = stream_read(socket);
    stream_write(socket, data);
}

int uv_main(int argc, char **argv) {
    uv_stream_t *client, *server;
    char addr[UV_MAXHOSTNAMESIZE] = nil;

    if (snprintf(addr, sizeof(addr), "0.0.0.0:%d", DEFAULT_PORT)) {
        server = stream_bind(addr, 0);
        while (server) {
            if (is_empty(client = stream_listen(server, DEFAULT_BACKLOG))) {
                fprintf(stderr, "Listen error %s\n", uv_strerror(coro_err_code()));
                break;
            }

            stream_handler(new_connection, client);
        }
    }

    return coro_err_code();
}

See branches for previous setup, main is an complete makeover of previous implementation approaches.

Similar approach has been made for C++20, an implementation in uvco. The tests presented there currently being reimplemented for C89 here, this project will be considered stable when completed. And another approach in libasync mixing libco with libuv. Both approaches are Linux only.

Synopsis

Usage

See examples and tests folder

Installation

The build system uses cmake, that produces static libraries by default.

Linux

mkdir build
cd build
cmake .. -D CMAKE_BUILD_TYPE=Debug/Release -D BUILD_EXAMPLES=ON -D BUILD_TESTS=ON # use to build files in tests/examples folder
cmake --build .

Windows

mkdir build
cd build
cmake .. -D BUILD_EXAMPLES=ON -D BUILD_TESTS=ON # use to build files in tests/examples folder
cmake --build . --config Debug/Release

Contributing

Contributions are encouraged and welcome; I am always happy to get feedback or pull requests on Github :) Create Github Issues for bugs and new features and comment on the ones you are interested in.

License

The MIT License (MIT). Please see License File for more information.

Releases

No releases published

Packages

No packages published