8abe33eb25a1b52b5131d0d24025d51f63077a71
[platform/upstream/nodejs.git] / src / timer_wrap.cc
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
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:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
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.
21
22 #include "node.h"
23 #include "handle_wrap.h"
24
25 namespace node {
26
27 using v8::Function;
28 using v8::FunctionCallbackInfo;
29 using v8::FunctionTemplate;
30 using v8::Handle;
31 using v8::HandleScope;
32 using v8::Integer;
33 using v8::Local;
34 using v8::Object;
35 using v8::String;
36 using v8::Value;
37
38 static Cached<String> ontimeout_sym;
39
40 class TimerWrap : public HandleWrap {
41  public:
42   static void Initialize(Handle<Object> target) {
43     HandleScope scope(node_isolate);
44
45     Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
46     constructor->InstanceTemplate()->SetInternalFieldCount(1);
47     constructor->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Timer"));
48
49     NODE_SET_METHOD(constructor, "now", Now);
50
51     NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
52     NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
53     NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
54
55     NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
56     NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
57     NODE_SET_PROTOTYPE_METHOD(constructor, "setRepeat", SetRepeat);
58     NODE_SET_PROTOTYPE_METHOD(constructor, "getRepeat", GetRepeat);
59     NODE_SET_PROTOTYPE_METHOD(constructor, "again", Again);
60
61     ontimeout_sym = FIXED_ONE_BYTE_STRING(node_isolate, "ontimeout");
62
63     target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Timer"),
64                 constructor->GetFunction());
65   }
66
67  private:
68   static void New(const FunctionCallbackInfo<Value>& args) {
69     // This constructor should not be exposed to public javascript.
70     // Therefore we assert that we are not trying to call this as a
71     // normal function.
72     assert(args.IsConstructCall());
73     HandleScope scope(node_isolate);
74     new TimerWrap(args.This());
75   }
76
77   explicit TimerWrap(Handle<Object> object)
78       : HandleWrap(object, reinterpret_cast<uv_handle_t*>(&handle_)) {
79     int r = uv_timer_init(uv_default_loop(), &handle_);
80     assert(r == 0);
81   }
82
83   ~TimerWrap() {
84   }
85
86   static void Start(const FunctionCallbackInfo<Value>& args) {
87     HandleScope scope(node_isolate);
88     TimerWrap* wrap;
89     NODE_UNWRAP(args.This(), TimerWrap, wrap);
90
91     int64_t timeout = args[0]->IntegerValue();
92     int64_t repeat = args[1]->IntegerValue();
93     int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
94     args.GetReturnValue().Set(err);
95   }
96
97   static void Stop(const FunctionCallbackInfo<Value>& args) {
98     HandleScope scope(node_isolate);
99     TimerWrap* wrap;
100     NODE_UNWRAP(args.This(), TimerWrap, wrap);
101
102     int err = uv_timer_stop(&wrap->handle_);
103     args.GetReturnValue().Set(err);
104   }
105
106   static void Again(const FunctionCallbackInfo<Value>& args) {
107     HandleScope scope(node_isolate);
108     TimerWrap* wrap;
109     NODE_UNWRAP(args.This(), TimerWrap, wrap);
110
111     int err = uv_timer_again(&wrap->handle_);
112     args.GetReturnValue().Set(err);
113   }
114
115   static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
116     HandleScope scope(node_isolate);
117     TimerWrap* wrap;
118     NODE_UNWRAP(args.This(), TimerWrap, wrap);
119
120     int64_t repeat = args[0]->IntegerValue();
121     uv_timer_set_repeat(&wrap->handle_, repeat);
122     args.GetReturnValue().Set(0);
123   }
124
125   static void GetRepeat(const FunctionCallbackInfo<Value>& args) {
126     HandleScope scope(node_isolate);
127     TimerWrap* wrap;
128     NODE_UNWRAP(args.This(), TimerWrap, wrap);
129
130     int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
131     args.GetReturnValue().Set(static_cast<double>(repeat));
132   }
133
134   static void OnTimeout(uv_timer_t* handle, int status) {
135     HandleScope scope(node_isolate);
136
137     TimerWrap* wrap = static_cast<TimerWrap*>(handle->data);
138     assert(wrap);
139
140     Local<Value> argv[1] = { Integer::New(status, node_isolate) };
141     MakeCallback(wrap->object(), ontimeout_sym, ARRAY_SIZE(argv), argv);
142   }
143
144   static void Now(const FunctionCallbackInfo<Value>& args) {
145     HandleScope scope(node_isolate);
146     double now = static_cast<double>(uv_now(uv_default_loop()));
147     args.GetReturnValue().Set(now);
148   }
149
150   uv_timer_t handle_;
151 };
152
153
154 }  // namespace node
155
156 NODE_MODULE(node_timer_wrap, node::TimerWrap::Initialize)