Ivan  Ivanov
Ivan Ivanov

Reputation: 2106

Is it normal to call uv_run several times?

I am new to uvlib. Is it normal to call uv_run twice if one wants to avoid blocking inside function? If not, then which instruments are available, except threads? Here I just open and close file.

#include <uv.h>
#include <stdio.h>
#include <fcntl.h>
#include <conio.h>
#ifdef _WIN32
    #include <conio.h>
    #include <Windows.h>
    #define Sleep(x) Sleep(x)
#else
    #include <unistd.h>
    #define Sleep(x) sleep(x)
#endif

uv_loop_t* loop;

uv_fs_t open_req;
uv_fs_t close_req;

void open_cb(uv_fs_t*);
void close_cb(uv_fs_t*);

const char *filename = "C:/c/somedata.txt";

int main(int argc, char **argv) {
    int r;

    loop = uv_loop_new();

    r = uv_fs_open(loop, &open_req, filename, O_RDONLY, S_IREAD, open_cb);
    if (r < 0) {
        printf("Error at opening file: %s\n", uv_strerror(r));
    }
    printf("in main now\n");
    uv_run(loop, UV_RUN_DEFAULT);
    uv_loop_close(loop);
    return 0;
}

void open_cb(uv_fs_t* req) {
    int result = req->result;

    if (result < 0) {
        printf("Error at opening file: %s\n", uv_strerror(result));
    } else {
        printf("Successfully opened file.\n");
    }
    uv_fs_req_cleanup(req);
    uv_fs_close(loop, &close_req, result, close_cb);
    uv_run(loop, UV_RUN_DEFAULT);
    Sleep(5000);
    printf("ok now\n");
}

void close_cb(uv_fs_t* req) {
    int result = req->result;
    printf("in close_cb now\n");

    if (result < 0) {
        printf("Error at closing file: %s\n", uv_strerror(result));
    } else {
        printf("Successfully closed file.\n");
    }
}

Upvotes: 1

Views: 622

Answers (1)

skypjack
skypjack

Reputation: 50550

Set aside your example, libuv offers the opportunity to run the loop more than once.
See the documentation for further details.

In particular, uv_run function accepts a parameter of type uv_run_mode.
Possible values are:

  • UV_RUN_DEFAULT: it doesn't stop unless you explicitly stop it and until there exists at least on referenced or active resource on the loop.

  • UV_RUN_ONCE: poll for I/O once and execute all the functions that are ready to be served. It has the drawback that it is blocking if there are no pending callbacks.

  • UV_RUN_NOWAIT: this is probably the one you are looking for, similar to the previous one, but it doesn't block if there are no pending callbacks.

Note that with both UV_RUN_ONCE and UV_RUN_NOWAIT you'll have to run the loop more than once.
Return value usually indicates if there are some other pending callbacks. In this case, the loop must be run sooner or later in the future.

The last mode, UV_RUN_NOWAIT, is probably the one you are looking for.
As an example, it can be used in scenarios where the client has its own loop and cannot block on the libuv's one.


Is it normal to run the loop more than once?
Well, yes, but it mostly depends on your actual problem if it's right.
It's hard to say from a 100 line snippet on SO.

Upvotes: 1

Related Questions