1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "async-wrap.h"
23 #include "async-wrap-inl.h"
26 #include "handle_wrap.h"
36 using v8::FunctionCallbackInfo;
37 using v8::FunctionTemplate;
39 using v8::HandleScope;
45 const uint32_t kOnTimeout = 0;
47 class TimerWrap : public HandleWrap {
49 static void Initialize(Handle<Object> target,
51 Handle<Context> context) {
52 Environment* env = Environment::GetCurrent(context);
53 Local<FunctionTemplate> constructor = FunctionTemplate::New(env->isolate(),
55 constructor->InstanceTemplate()->SetInternalFieldCount(1);
56 constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Timer"));
57 constructor->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnTimeout"),
58 Integer::New(env->isolate(), kOnTimeout));
60 NODE_SET_METHOD(constructor, "now", Now);
62 NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
63 NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
64 NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
66 NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
67 NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
68 NODE_SET_PROTOTYPE_METHOD(constructor, "setRepeat", SetRepeat);
69 NODE_SET_PROTOTYPE_METHOD(constructor, "getRepeat", GetRepeat);
70 NODE_SET_PROTOTYPE_METHOD(constructor, "again", Again);
72 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Timer"),
73 constructor->GetFunction());
77 static void New(const FunctionCallbackInfo<Value>& args) {
78 // This constructor should not be exposed to public javascript.
79 // Therefore we assert that we are not trying to call this as a
81 assert(args.IsConstructCall());
82 HandleScope handle_scope(args.GetIsolate());
83 Environment* env = Environment::GetCurrent(args.GetIsolate());
84 new TimerWrap(env, args.This());
87 TimerWrap(Environment* env, Handle<Object> object)
90 reinterpret_cast<uv_handle_t*>(&handle_),
91 AsyncWrap::PROVIDER_TIMERWRAP) {
92 int r = uv_timer_init(env->event_loop(), &handle_);
99 static void Start(const FunctionCallbackInfo<Value>& args) {
100 Environment* env = Environment::GetCurrent(args.GetIsolate());
101 HandleScope scope(env->isolate());
102 TimerWrap* wrap = Unwrap<TimerWrap>(args.This());
104 int64_t timeout = args[0]->IntegerValue();
105 int64_t repeat = args[1]->IntegerValue();
106 int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
107 args.GetReturnValue().Set(err);
110 static void Stop(const FunctionCallbackInfo<Value>& args) {
111 Environment* env = Environment::GetCurrent(args.GetIsolate());
112 HandleScope scope(env->isolate());
113 TimerWrap* wrap = Unwrap<TimerWrap>(args.This());
115 int err = uv_timer_stop(&wrap->handle_);
116 args.GetReturnValue().Set(err);
119 static void Again(const FunctionCallbackInfo<Value>& args) {
120 Environment* env = Environment::GetCurrent(args.GetIsolate());
121 HandleScope scope(env->isolate());
122 TimerWrap* wrap = Unwrap<TimerWrap>(args.This());
124 int err = uv_timer_again(&wrap->handle_);
125 args.GetReturnValue().Set(err);
128 static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
129 Environment* env = Environment::GetCurrent(args.GetIsolate());
130 HandleScope scope(env->isolate());
131 TimerWrap* wrap = Unwrap<TimerWrap>(args.This());
133 int64_t repeat = args[0]->IntegerValue();
134 uv_timer_set_repeat(&wrap->handle_, repeat);
135 args.GetReturnValue().Set(0);
138 static void GetRepeat(const FunctionCallbackInfo<Value>& args) {
139 Environment* env = Environment::GetCurrent(args.GetIsolate());
140 HandleScope scope(env->isolate());
141 TimerWrap* wrap = Unwrap<TimerWrap>(args.This());
143 int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
144 args.GetReturnValue().Set(static_cast<double>(repeat));
147 static void OnTimeout(uv_timer_t* handle, int status) {
148 TimerWrap* wrap = static_cast<TimerWrap*>(handle->data);
149 Environment* env = wrap->env();
150 HandleScope handle_scope(env->isolate());
151 Context::Scope context_scope(env->context());
152 Local<Value> argv[1] = { Integer::New(env->isolate(), status) };
153 wrap->MakeCallback(kOnTimeout, ARRAY_SIZE(argv), argv);
156 static void Now(const FunctionCallbackInfo<Value>& args) {
157 HandleScope handle_scope(args.GetIsolate());
158 Environment* env = Environment::GetCurrent(args.GetIsolate());
159 uv_update_time(env->event_loop());
160 double now = static_cast<double>(uv_now(env->event_loop()));
161 args.GetReturnValue().Set(now);
170 NODE_MODULE_CONTEXT_AWARE_BUILTIN(timer_wrap, node::TimerWrap::Initialize)