Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-sleep / src / mrb_sleep.c
1 /*
2 ** mrb_sleep - sleep methods for mruby
3 **
4 ** Copyright (c) mod_mruby developers 2012-
5 ** Copyright (c) mruby developers 2018
6 **
7 ** Permission is hereby granted, free of charge, to any person obtaining
8 ** a copy of this software and associated documentation files (the
9 ** "Software"), to deal in the Software without restriction, including
10 ** without limitation the rights to use, copy, modify, merge, publish,
11 ** distribute, sublicense, and/or sell copies of the Software, and to
12 ** permit persons to whom the Software is furnished to do so, subject to
13 ** the following conditions:
14 **
15 ** The above copyright notice and this permission notice shall be
16 ** included in all copies or substantial portions of the Software.
17 **
18 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **
26 ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
27 */
28
29 #include <time.h>
30 #ifdef _WIN32
31     #include <windows.h>
32     #define sleep(x) Sleep(x * 1000)
33     #define usleep(x) Sleep((DWORD)(((x)<1000) ? 1 : ((x)/1000)))
34 #else
35     #include <unistd.h>
36     #include <sys/time.h>
37 #endif
38
39 #include "mruby.h"
40
41 /* not implemented forever sleep (called without an argument)*/
42 static mrb_value
43 mrb_f_sleep(mrb_state *mrb, mrb_value self)
44 {
45     time_t beg = time(0);
46     time_t end;
47 #ifndef MRB_WITHOUT_FLOAT
48     mrb_float sec;
49
50     mrb_get_args(mrb, "f", &sec);
51     if (sec >= 0) {
52         usleep(sec * 1000000);
53     }
54     else {
55         mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative");
56     }
57 #else
58     mrb_int sec;
59
60     mrb_get_args(mrb, "i", &sec);
61     if (sec >= 0) {
62         sleep(sec);
63     } else {
64         mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative");
65     }
66 #endif
67     end = time(0) - beg;
68
69     return mrb_fixnum_value(end);
70 }
71
72 /* mruby special; needed for mruby without float numbers */
73 static mrb_value
74 mrb_f_usleep(mrb_state *mrb, mrb_value self)
75 {
76     mrb_int usec;
77 #ifdef _WIN32
78     FILETIME st_ft,ed_ft;
79     unsigned __int64 st_time = 0;
80     unsigned __int64 ed_time = 0;
81 #else
82     struct timeval st_tm,ed_tm;
83 #endif
84     time_t slp_tm;
85
86 #ifdef _WIN32
87     GetSystemTimeAsFileTime(&st_ft);
88 #else
89     gettimeofday(&st_tm, NULL);
90 #endif
91
92     /* not implemented forever sleep (called without an argument)*/
93     mrb_get_args(mrb, "i", &usec);
94
95     if (usec >= 0) {
96         usleep(usec);
97     } else {
98         mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative integer");
99     }
100
101 #ifdef _WIN32
102     GetSystemTimeAsFileTime(&ed_ft);
103
104     st_time |= st_ft.dwHighDateTime;
105     st_time <<=32;
106     st_time |= st_ft.dwLowDateTime;
107     ed_time |= ed_ft.dwHighDateTime;
108     ed_time <<=32;
109     ed_time |= ed_ft.dwLowDateTime;
110
111     slp_tm = (ed_time - st_time) / 10;
112 #else
113     gettimeofday(&ed_tm, NULL);
114
115     if (st_tm.tv_usec > ed_tm.tv_usec) {
116         slp_tm = 1000000 + ed_tm.tv_usec - st_tm.tv_usec;
117     }
118     else {
119         slp_tm = ed_tm.tv_usec - st_tm.tv_usec;
120     }
121 #endif
122
123     return mrb_fixnum_value(slp_tm);
124 }
125
126 void
127 mrb_mruby_sleep_gem_init(mrb_state *mrb)
128 {
129     mrb_define_method(mrb, mrb->kernel_module, "sleep",   mrb_f_sleep,   MRB_ARGS_REQ(1));
130     mrb_define_method(mrb, mrb->kernel_module, "usleep",  mrb_f_usleep,  MRB_ARGS_REQ(1));
131 }
132
133 void
134 mrb_mruby_sleep_gem_final(mrb_state *mrb)
135 {
136 }