1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include "iotjs_def.h"
17 #include "iotjs_module_timer.h"
20 static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap);
21 static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap);
24 iotjs_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer) {
25 iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t);
26 IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_timerwrap_t, timerwrap);
28 iotjs_handlewrap_initialize(&_this->handlewrap, jtimer,
29 (uv_handle_t*)(&_this->handle),
30 (JFreeHandlerType)iotjs_timerwrap_destroy);
32 // Initialize timer handler.
33 const iotjs_environment_t* env = iotjs_environment_get();
34 uv_timer_init(iotjs_environment_loop(env), &_this->handle);
40 static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap) {
41 IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_timerwrap_t, timerwrap);
42 iotjs_handlewrap_destroy(&_this->handlewrap);
44 IOTJS_RELEASE(timerwrap);
48 // This function is called from uv when timeout expires.
49 static void TimeoutHandler(uv_timer_t* handle) {
50 // Find timer wrap from handle.
51 iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_handle(handle);
53 // Call the timeout handler.
54 iotjs_timerwrap_on_timeout(timer_wrap);
58 int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, int64_t timeout,
60 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
63 return uv_timer_start(&_this->handle, TimeoutHandler, timeout, repeat);
67 int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap) {
68 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
70 if (!uv_is_closing(iotjs_handlewrap_get_uv_handle(&_this->handlewrap))) {
71 iotjs_handlewrap_close(&_this->handlewrap, NULL);
78 static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap) {
79 IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_timerwrap_t, timerwrap);
81 // Call javascript timeout handler function.
82 const iotjs_jval_t* jobject = iotjs_timerwrap_jobject(timerwrap);
83 iotjs_jval_t jcallback =
84 iotjs_jval_get_property(jobject, IOTJS_MAGIC_STRING_HANDLETIMEOUT);
85 iotjs_make_callback(&jcallback, jobject, iotjs_jargs_get_empty());
86 iotjs_jval_destroy(&jcallback);
90 uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap) {
91 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
92 return &_this->handle;
96 iotjs_jval_t* iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap) {
97 IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
98 iotjs_jval_t* jobject = iotjs_handlewrap_jobject(&_this->handlewrap);
99 IOTJS_ASSERT(iotjs_jval_is_object(jobject));
104 iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle) {
105 uv_handle_t* handle = (uv_handle_t*)(timer_handle);
106 iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
107 iotjs_timerwrap_t* timerwrap = (iotjs_timerwrap_t*)handlewrap;
108 IOTJS_ASSERT(iotjs_timerwrap_handle(timerwrap) == timer_handle);
113 iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const iotjs_jval_t* jtimer) {
114 iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtimer);
115 return (iotjs_timerwrap_t*)handlewrap;
119 JHANDLER_FUNCTION(Start) {
121 JHANDLER_CHECK_THIS(object);
122 JHANDLER_CHECK_ARGS(2, number, number);
124 const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
127 iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
130 int64_t timeout = JHANDLER_GET_ARG(0, number);
131 int64_t repeat = JHANDLER_GET_ARG(1, number);
134 int res = iotjs_timerwrap_start(timer_wrap, timeout, repeat);
136 iotjs_jhandler_return_number(jhandler, res);
140 JHANDLER_FUNCTION(Stop) {
141 JHANDLER_CHECK_THIS(object);
143 const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
145 iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
148 int res = iotjs_timerwrap_stop(timer_wrap);
150 iotjs_jhandler_return_number(jhandler, res);
154 JHANDLER_FUNCTION(Timer) {
155 JHANDLER_CHECK_THIS(object);
157 const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
159 iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_create(jtimer);
160 IOTJS_ASSERT(iotjs_jval_is_object(iotjs_timerwrap_jobject(timer_wrap)));
161 IOTJS_ASSERT(iotjs_jval_get_object_native_handle(jtimer) != 0);
165 iotjs_jval_t InitTimer() {
166 iotjs_jval_t timer = iotjs_jval_create_function_with_dispatch(Timer);
168 iotjs_jval_t prototype = iotjs_jval_create_object();
169 iotjs_jval_set_property_jval(&timer, IOTJS_MAGIC_STRING_PROTOTYPE,
172 iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_START, Start);
173 iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_STOP, Stop);
175 iotjs_jval_destroy(&prototype);