Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@lzace817
Copy link

@lzace817 lzace817 commented Sep 19, 2025

Current documentation have feelings, uv_timer_t. this pr makes it at least not misleading.

#include <stdio.h>
#include <time.h>
#include <assert.h>

#include <unistd.h>

#include "uv.h"

#define TIMESCALE 1
// #define TIMESCALE 50

static int64_t base;

static int64_t now_ms(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (int64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

static void busy_20ms(void)
{
    int64_t timestamp = now_ms();

    while (now_ms() - timestamp < 20) ;
}

static void sleep_20ms(void) {
    struct timespec req = { .tv_sec = 0, .tv_nsec = 20 * 1000 * 1000 }; // 20 ms
    while (nanosleep(&req, &req) == -1) ;
}

static void tick(uv_timer_t* handle)
{
    uv_timer_again(handle);
    printf("begin: %ld\n", now_ms() - base);
    // usleep(500);
    // sleep(1);
    // sleep_20ms();
    busy_20ms();
    printf("end:   %ld\n", now_ms() - base);
}

static void done(uv_timer_t* handle)
{
    printf("done!\n");
}

int main(void)
{
    uv_loop_t *loop = uv_default_loop();

    uv_timer_t step;
    uv_timer_init(loop, &step);
    uv_unref((uv_handle_t *)&step);
    uv_timer_start(&step, tick, 0, 50 * TIMESCALE);

    uv_timer_t timeout;
    uv_timer_init(loop, &timeout);
    uv_timer_start(&timeout, done, 170 * TIMESCALE, 0);

    base = now_ms();

    return uv_run(loop, UV_RUN_DEFAULT);
}

result:

$ ./feelings 
begin: 0
end:   20
begin: 50
end:   70
begin: 100
end:   120
begin: 150
end:   170
done!

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this belongs more closely in uv__next_timeout, so we don't update unless we'll actually use the new value?

@bnoordhuis
Copy link
Member

Libuv deliberately doesn't update loop->time frequently because querying the system for the current time can be expensive. It's why uv_update_time() exists.

@saghul
Copy link
Member

saghul commented Sep 20, 2025

Agreed with Ben here. Also, I think the change would break applications as this behavior has been in place for a really long time.

@vtjnash
Copy link
Member

vtjnash commented Sep 20, 2025

Just before doing a very expensive epoll syscall for a long timeout is probably a good time to adjust to get the right timeout though

@vtjnash
Copy link
Member

vtjnash commented Sep 20, 2025

It is unfortunate that kernel designers opted for relative timeouts here, since it makes the respective syscalls more expensive and a bit less reliable than if they allowed doing absolute timeouts :/

@bnoordhuis
Copy link
Member

Just before doing a very expensive epoll syscall for a long timeout is probably a good time to adjust to get the right timeout though

I don't disagree but Saúl is right it's a user-visible change. It could be done as an opt-in uv_loop_configure() flag though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants