Permalink
Browse files

Timer, refactor: use the TimeoutScope class to implement timeout.

  • Loading branch information...
xicilion committed Aug 4, 2018
1 parent 70b6a8f commit d89e439f4535e3a7637a2078386677fc230e2651
Showing with 63 additions and 49 deletions.
  1. +60 −0 fibjs/include/Timer.h
  2. +3 −49 fibjs/src/global/timeout.cpp
View
@@ -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
@@ -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.