Commit 0e6088ec authored by Kirill Smelkov's avatar Kirill Smelkov

time: Offload users from thinking about refptr

Rearrange time C++ API so that e.g. time.Ticker is already
refptr<time._Ticker>. This way time users don't need to write refptr
all the time.
parent 5f76f363
......@@ -61,13 +61,11 @@ cdef extern from "golang/time.h" namespace "golang::time" nogil:
chan[double] after(double dt)
Timer after_func(double dt, ...) # ... = std::function<void()>
# pyx _Ticker = raw C++ Ticker
cppclass _Ticker "Ticker":
cppclass _Ticker:
chan[double] c
void stop()
# pyx Ticker = C++ refptr<Ticker>
cppclass Ticker "golang::refptr<golang::time::Ticker>" (refptr[_Ticker]):
cppclass Ticker (refptr[_Ticker]):
# Ticker.X = Ticker->X in C++.
chan[double] c "_ptr()->c"
void stop "_ptr()->stop" ()
......@@ -75,14 +73,12 @@ cdef extern from "golang/time.h" namespace "golang::time" nogil:
Ticker new_ticker(double dt)
# pyx _Timer = raw C++ Timer
cppclass _Timer "Timer":
cppclass _Timer:
chan[double] c
cbool stop()
void reset(double dt)
# pyx Timer = C++ refptr<Timer>
cppclass Timer "golang::refptr<golang::time::Timer>" (refptr[_Timer]):
cppclass Timer (refptr[_Timer]):
# Timer.X = Timer->X in C++.
chan[double] c "_ptr()->c"
cbool stop "_ptr()->stop" ()
......
......@@ -34,9 +34,9 @@ namespace time {
// ---- timers ----
// FIXME timers are implemented very inefficiently - each timer currently consumes a goroutine.
refptr<Ticker> new_ticker(double dt);
refptr<Timer> new_timer (double dt);
refptr<Timer> _new_timer(double dt, function<void()>);
Ticker new_ticker(double dt);
Timer new_timer (double dt);
Timer _new_timer(double dt, function<void()>);
chan<double> tick(double dt) {
......@@ -49,23 +49,23 @@ chan<double> after(double dt) {
return new_timer(dt)->c;
}
refptr<Timer> after_func(double dt, function<void()> f) {
Timer after_func(double dt, function<void()> f) {
return _new_timer(dt, f);
}
// Ticker
Ticker::Ticker() {}
Ticker::~Ticker() {}
void Ticker::decref() {
_Ticker::_Ticker() {}
_Ticker::~_Ticker() {}
void _Ticker::decref() {
if (__decref())
delete this;
}
refptr<Ticker> new_ticker(double dt) {
Ticker new_ticker(double dt) {
if (dt <= 0)
panic("ticker: dt <= 0");
refptr<Ticker> tx = adoptref(new Ticker());
Ticker tx = adoptref(new _Ticker());
tx->c = makechan<double>(1); // 1-buffer -- same as in Go
tx->_dt = dt;
tx->_stop = false;
......@@ -75,8 +75,8 @@ refptr<Ticker> new_ticker(double dt) {
return tx;
}
void Ticker::stop() {
Ticker &tx = *this;
void _Ticker::stop() {
_Ticker &tx = *this;
tx._mu.lock();
tx._stop = true;
......@@ -87,8 +87,8 @@ void Ticker::stop() {
tx._mu.unlock();
}
void Ticker::_tick() {
Ticker &tx = *this;
void _Ticker::_tick() {
_Ticker &tx = *this;
while (1) {
// XXX adjust for accumulated error δ?
......@@ -113,15 +113,15 @@ void Ticker::_tick() {
// Timer
Timer::Timer() {}
Timer::~Timer() {}
void Timer::decref() {
_Timer::_Timer() {}
_Timer::~_Timer() {}
void _Timer::decref() {
if (__decref())
delete this;
}
refptr<Timer> _new_timer(double dt, function<void()> f) {
refptr<Timer> t = adoptref(new Timer());
Timer _new_timer(double dt, function<void()> f) {
Timer t = adoptref(new _Timer());
t->c = (f == NULL ? makechan<double>(1) : NULL);
t->_f = f;
t->_dt = INFINITY;
......@@ -130,12 +130,12 @@ refptr<Timer> _new_timer(double dt, function<void()> f) {
return t;
}
refptr<Timer> new_timer(double dt) {
Timer new_timer(double dt) {
return _new_timer(dt, NULL);
}
bool Timer::stop() {
Timer &t = *this;
bool _Timer::stop() {
_Timer &t = *this;
bool canceled;
t._mu.lock();
......@@ -157,8 +157,8 @@ bool Timer::stop() {
return canceled;
}
void Timer::reset(double dt) {
Timer &t = *this;
void _Timer::reset(double dt) {
_Timer &t = *this;
t._mu.lock();
if (t._dt != INFINITY) {
......@@ -168,15 +168,15 @@ void Timer::reset(double dt) {
t._dt = dt;
t._ver += 1;
// TODO rework timers so that new timer does not spawn new goroutine.
refptr<Timer> tref = newref(&t); // pass t reference to spawned goroutine
Timer tref = newref(&t); // pass t reference to spawned goroutine
go([tref, dt](int ver) {
tref->_fire(dt, ver);
}, t._ver);
t._mu.unlock();
}
void Timer::_fire(double dt, int ver) {
Timer &t = *this;
void _Timer::_fire(double dt, int ver) {
_Timer &t = *this;
sleep(dt);
t._mu.lock();
......
......@@ -74,8 +74,10 @@ LIBGOLANG_API void sleep(double dt);
LIBGOLANG_API double now();
class Ticker;
class Timer;
class _Ticker;
class _Timer;
typedef refptr<_Ticker> Ticker;
typedef refptr<_Timer> Timer;
// tick returns channel connected to dt ticker.
//
......@@ -92,17 +94,17 @@ LIBGOLANG_API chan<double> after(double dt);
//
// The function will be called in its own goroutine.
// Returned timer can be used to cancel the call.
LIBGOLANG_API refptr<Timer> after_func(double dt, std::function<void()> f);
LIBGOLANG_API Timer after_func(double dt, std::function<void()> f);
// new_ticker creates new Ticker that will be firing at dt intervals.
LIBGOLANG_API refptr<Ticker> new_ticker(double dt);
LIBGOLANG_API Ticker new_ticker(double dt);
// Ticker arranges for time events to be sent to .c channel on dt-interval basis.
//
// If the receiver is slow, Ticker does not queue events and skips them.
// Ticking can be canceled via .stop() .
struct Ticker : refobj {
struct _Ticker : refobj {
chan<double> c;
private:
......@@ -112,9 +114,9 @@ private:
// don't new - create only via new_ticker()
private:
Ticker();
~Ticker();
friend refptr<Ticker> new_ticker(double dt);
_Ticker();
~_Ticker();
friend Ticker new_ticker(double dt);
public:
LIBGOLANG_API void decref();
......@@ -130,12 +132,12 @@ private:
// new_timer creates new Timer that will fire after dt.
LIBGOLANG_API refptr<Timer> new_timer(double dt);
LIBGOLANG_API Timer new_timer(double dt);
// Timer arranges for time event to be sent to .c channel after dt time.
//
// The timer can be stopped (.stop), or reinitialized to another time (.reset).
struct Timer : refobj {
struct _Timer : refobj {
chan<double> c;
private:
......@@ -147,9 +149,9 @@ private:
// don't new - create only via new_timer() & co
private:
Timer();
~Timer();
friend refptr<Timer> _new_timer(double dt, std::function<void()> f);
_Timer();
~_Timer();
friend Timer _new_timer(double dt, std::function<void()> f);
public:
LIBGOLANG_API void decref();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment