skypjack / uvw

Header-only, event based, tiny and easy to use libuv wrapper in modern C++ - now available as also shared/static library!
MIT License
1.84k stars 209 forks source link

Found a bug in TimerHandle #234

Closed rmalizia44 closed 3 years ago

rmalizia44 commented 3 years ago

Hi, I've discovered that if you create a TimerHandle and start it and its repeat value is zero, the timer will stop after the first callback, will leave the loop, will not call the CloseEvent and will not release it's data shared_ptr. I've made a minimal example that replicate the bug:

#include <iostream>
#include "uvw.hpp"

struct Test {
    Test()  { std::cout << "[+]" << std::endl; }
    ~Test() { std::cout << "[-]" << std::endl; }
};

int main() {
    auto loop = uvw::Loop::getDefault();

    auto timer = loop->resource<uvw::TimerHandle>();
    timer->start(std::chrono::milliseconds(100), std::chrono::milliseconds(0));
    timer->data(std::make_shared<Test>());
    timer->on<uvw::TimerEvent>([](const uvw::TimerEvent& event, uvw::TimerHandle& handle) {
        std::cout << "time!" << std::endl;
    });
    timer->on<uvw::CloseEvent>([](const uvw::CloseEvent& event, uvw::TimerHandle& handle) {
        std::cout << "closed" << std::endl;
    });

    loop->run();
}

Expected Output:

[+]
time!
closed
[-]

But I've got this:

[+]
time!

Compiled with MinGW32 Windows x64 g++ g++ -o test ./test.cpp -Wall -Werror -I. -std=c++17 -luv && ./test

Sorry for the unconvenience but I'm relatively new to uvw

skypjack commented 3 years ago

uvw doesn't close handles for the user. It stays true to how libuv works and therefore you have to close them. That's one of the reasons for which the handle itself is passed back to the listeners. You must invoke .close when you receive a TimerEvent to observe the desired behavior.

skypjack commented 3 years ago

I assume this was answered and therefore I'm closing the issue. Feel free to continue the discussion here if needed. Thanks.