Skip to content

Commit

Permalink
Timer, refactor: use the TimeoutScope class to implement timeout.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Aug 4, 2018
1 parent 70b6a8f commit d89e439
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 49 deletions.
60 changes: 60 additions & 0 deletions fibjs/include/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,66 @@ class JSTimer : public Timer {
QuickArray<v8::Global<v8::Value>> m_argv;
v8::Global<v8::Function> m_callback;
};

class TimeoutScope {
private:
class FuncTimer : public JSTimer {
public:
FuncTimer(JSFiber* fiber, int32_t timeout)
: JSTimer(timeout, false, true)
, m_fiber(fiber)
{
}

public:
virtual void on_js_timer()
{
m_fiber->m_termed = true;
if (JSFiber::current() == m_fiber)
m_fiber->holder()->m_isolate->TerminateExecution();
}

private:
obj_ptr<JSFiber> m_fiber;
};

public:
TimeoutScope(double timeout)
: m_isolate(Isolate::current())
, this_fiber(JSFiber::current())
, m_timer(new FuncTimer(this_fiber, (int32_t)timeout))
{
if (timeout < 1 || timeout > TIMEOUT_MAX)
timeout = 1;

m_timer->sleep();
}

result_t result()
{
m_timer->clear();

if (try_catch.HasCaught()) {
if (this_fiber->m_termed) {
try_catch.Reset();
this_fiber->m_termed = false;
m_isolate->m_isolate->CancelTerminateExecution();
return CHECK_ERROR(CALL_E_TIMEOUT);
} else {
try_catch.ReThrow();
return CHECK_ERROR(CALL_E_JAVASCRIPT);
}
}

return 0;
}

public:
TryCatch try_catch;
Isolate* m_isolate;
obj_ptr<JSFiber> this_fiber;
obj_ptr<JSTimer> m_timer;
};
}

#endif
52 changes: 3 additions & 49 deletions fibjs/src/global/timeout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,19 @@
*/

#include "object.h"
#include "utils.h"
#include "QuickArray.h"
#include "ifs/global.h"
#include "ifs/timers.h"
#include "Timer.h"

namespace fibjs {

class FuncTimer : public JSTimer {
public:
FuncTimer(JSFiber* fiber, int32_t timeout)
: JSTimer(timeout, false, true)
, m_fiber(fiber)
{
}

public:
virtual void on_js_timer()
{
m_fiber->m_termed = true;
if (JSFiber::current() == m_fiber)
m_fiber->holder()->m_isolate->TerminateExecution();
}

private:
obj_ptr<JSFiber> m_fiber;
};

result_t timers_base::call(v8::Local<v8::Function> func, double timeout,
OptArgs args, v8::Local<v8::Value>& retVal)
{
if (timeout < 1 || timeout > TIMEOUT_MAX)
timeout = 1;

Isolate* isolate = Isolate::current();
obj_ptr<JSFiber> this_fiber = JSFiber::current();
std::vector<v8::Local<v8::Value>> argv;

args.GetData(argv);

obj_ptr<JSTimer> timer = new FuncTimer(this_fiber, (int32_t)timeout);

TryCatch try_catch;

timer->sleep();
retVal = func->Call(v8::Undefined(isolate->m_isolate), (int32_t)argv.size(), argv.data());
timer->clear();

if (try_catch.HasCaught()) {
if (this_fiber->m_termed) {
this_fiber->m_termed = false;
isolate->m_isolate->CancelTerminateExecution();
return CHECK_ERROR(CALL_E_TIMEOUT);
} else {
try_catch.ReThrow();
return CHECK_ERROR(CALL_E_JAVASCRIPT);
}
}

return 0;
TimeoutScope ts(timeout);
retVal = func->Call(v8::Undefined(ts.m_isolate->m_isolate), (int32_t)argv.size(), argv.data());
return ts.result();
}
}

0 comments on commit d89e439

Please sign in to comment.