Skip to content

Commit

Permalink
timer: add optional support for rust event loop (#48130)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkarneges authored Feb 20, 2025
1 parent 67e663b commit 6997a41
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
32 changes: 32 additions & 0 deletions src/core/eventlooptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "defercall.h"
#include "eventloop.h"
#include "socketnotifier.h"
#include "timer.h"

class EventLoopTest : public QObject
{
Expand Down Expand Up @@ -62,6 +63,37 @@ private slots:
close(fds[1]);
close(fds[0]);
}

void timer()
{
EventLoop loop(2);

Timer *t1 = new Timer;
Timer *t2 = new Timer;

int timeoutCount = 0;

t1->timeout.connect([&] {
++timeoutCount;
});

t2->timeout.connect([&] {
++timeoutCount;
loop.exit(123);
});

t1->setSingleShot(true);
t1->start(0);

t2->setSingleShot(true);
t2->start(0);

QCOMPARE(loop.exec(), 123);
QCOMPARE(timeoutCount, 2);

delete t2;
delete t1;
}
};

namespace {
Expand Down
46 changes: 38 additions & 8 deletions src/core/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <QDateTime>
#include <QTimer>
#include "timerwheel.h"
#include "eventloop.h"

#define TICK_DURATION_MS 10
#define UPDATE_TICKS_MAX 1000
Expand Down Expand Up @@ -174,6 +175,7 @@ void TimerManager::updateTimeout(qint64 currentTime)
static thread_local TimerManager *g_manager = 0;

Timer::Timer() :
loop_(EventLoop::instance()),
singleShot_(false),
interval_(0),
timerId_(-1)
Expand Down Expand Up @@ -208,29 +210,57 @@ void Timer::start(int msec)

void Timer::start()
{
// must call Timer::init first
assert(g_manager);

stop();

int id = g_manager->add(interval_, this);
assert(id >= 0);
if(loop_)
{
// if the rust-based eventloop is available, use it

int id = loop_->registerTimer(interval_, Timer::cb_timer_activated, this);
assert(id >= 0);

timerId_ = id;
}
else
{
// else fall back to qt eventloop

// must call Timer::init first
assert(g_manager);

int id = g_manager->add(interval_, this);
assert(id >= 0);

timerId_ = id;
timerId_ = id;
}
}

void Timer::stop()
{
if(timerId_ >= 0)
{
assert(g_manager);
if(loop_)
{
loop_->deregister(timerId_);
}
else
{
assert(g_manager);

g_manager->remove(timerId_);
g_manager->remove(timerId_);
}

timerId_ = -1;
}
}

void Timer::cb_timer_activated(void *ctx)
{
Timer *self = (Timer *)ctx;

self->timerReady();
}

void Timer::timerReady()
{
timerId_ = -1;
Expand Down
3 changes: 3 additions & 0 deletions src/core/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

using Signal = boost::signals2::signal<void()>;

class EventLoop;
class TimerManager;

class Timer : public QObject
Expand Down Expand Up @@ -58,10 +59,12 @@ class Timer : public QObject
private:
friend class TimerManager;

EventLoop *loop_;
bool singleShot_;
int interval_;
int timerId_;

static void cb_timer_activated(void *ctx);
void timerReady();
};

Expand Down

0 comments on commit 6997a41

Please sign in to comment.