diff options
author | Aleksejs Sestakovs <aleksejs.sestakovs@zabbix.com> | 2022-01-13 09:46:55 +0300 |
---|---|---|
committer | Aleksejs Sestakovs <aleksejs.sestakovs@zabbix.com> | 2022-01-13 09:52:12 +0300 |
commit | e2f9621231721fe42d3ce0f8017eb116cd381f4f (patch) | |
tree | 8148e6771c221ba24e80903173f3552a2aec2f57 /src/libs | |
parent | ad945f1c619d9d67c3d54f76ab31a34a98c3138b (diff) |
.......PS. [ZBXNEXT-7101] implemented sleep function into JS engine
* commit '7549be27f9b9f1cd6564997a21f67a72c134ce24':
.......PS. [ZBXNEXT-7101] fixed to accept zero value
.......PS. [ZBXNEXT-7101] fixed to accept number in string format
.......PS. [ZBXNEXT-7101] reworked timeout error check
.......PS. [ZBXNEXT-7101] fixed error check
.......PS. [ZBXNEXT-7101] added timeout validation
.......PS. [ZBXNEXT-7101] renamed Sleep() to sleep()
........S. [ZBXNEXT-7101] changed msleep() function to method of Zabbix object
........S. [ZBXNEXT-7101] implemented sleep function into JS engine
(cherry picked from commit 7c0e02e9d346f4d5e13400ad6ff8438adef70d78)
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/zbxembed/zabbix.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/src/libs/zbxembed/zabbix.c b/src/libs/zbxembed/zabbix.c index 1daaa58bcaa..c9477bdda1f 100644 --- a/src/libs/zbxembed/zabbix.c +++ b/src/libs/zbxembed/zabbix.c @@ -110,9 +110,81 @@ out: return 0; } +/****************************************************************************** + * * + * Function: es_zabbix_sleep * + * * + * Purpose: sleep for given duration in milliseconds * + * * + * Parameters: ctx - [IN] pointer to duk_context * + * * + * Comments: Throws an error: * + * - if the top value at ctx value stack cannot be converted to * + * unsigned integer * + * - if the sleep duration is longer than timeout * + * - if the sleep duration is longer than time left for JS * + * execution before timeout occurs * + * * + ******************************************************************************/ +static duk_ret_t es_zabbix_sleep(duk_context *ctx) +{ + zbx_es_env_t *env; + duk_memory_functions out_funcs; + struct timespec ts_sleep; + zbx_uint64_t timeout, duration; + unsigned int sleep_ms; + double sleep_dbl; + duk_idx_t err_idx = -1; + + /* use duk_to_number() instead of duk_to_uint() to distinguish between zero value and error */ + sleep_dbl = duk_to_number(ctx, 0); + + if (0 != DUK_ISNAN((float)sleep_dbl) || 0.0 > sleep_dbl) + return duk_error(ctx, DUK_ERR_EVAL_ERROR, "invalid Zabbix.sleep() duration"); + + if (DUK_UINT_MAX < sleep_dbl) + sleep_ms = DUK_UINT_MAX; + else + sleep_ms = (unsigned int)sleep_dbl; + + duk_get_memory_functions(ctx, &out_funcs); + env = (zbx_es_env_t *)out_funcs.udata; + timeout = (unsigned int)env->timeout * 1000; + + if (sleep_ms > timeout) + { + return duk_error(ctx, DUK_ERR_EVAL_ERROR, + "Zabbix.sleep(%u) duration is longer than JS execution timeout(" ZBX_FS_UI64 ")", + sleep_ms, timeout); + } + + duration = zbx_get_duration_ms(&env->start_time); + + if (timeout < duration) + return duk_error(ctx, DUK_ERR_RANGE_ERROR, "execution timeout"); + + timeout -= duration; + + if (sleep_ms > timeout) + { + err_idx = duk_push_error_object(ctx, DUK_ERR_RANGE_ERROR, "execution timeout"); + sleep_ms = (unsigned int)timeout; + } + + ts_sleep.tv_sec = sleep_ms / 1000; + ts_sleep.tv_nsec = sleep_ms % 1000 * 1000000; + nanosleep(&ts_sleep, NULL); + + if (-1 != err_idx) + return duk_throw(ctx); + + return 0; +} + static const duk_function_list_entry zabbix_methods[] = { - {"Log", es_zabbix_log, 2}, - {"log", es_zabbix_log, 2}, + {"Log", es_zabbix_log, 2}, + {"log", es_zabbix_log, 2}, + {"sleep", es_zabbix_sleep, 1}, {NULL, NULL, 0} }; |