https://www.mediawiki.org/wiki/Special:Code/MediaWiki/115070
Revision: 115070
Author: tstarling
Date: 2012-04-27 01:24:20 +0000 (Fri, 27 Apr 2012)
Log Message:
-----------
* Aggregate CPU usage for limit measurement across all calls against a given
sandbox object, instead of limiting per-call. Some interface changes were
required. Now the timer is stored in the sandbox object instead of the stack,
and it keeps track of its own limit settings.
* Provide LuaSandbox::getCPUUsage(), based on a separate timer so that it can
run after the limits have expired, or if there are no limits set.
* Adjusted pcall.phpt to make new sandbox objects after a timeout
Modified Paths:
--------------
trunk/php/luasandbox/luasandbox.c
trunk/php/luasandbox/luasandbox_timer.h
trunk/php/luasandbox/php_luasandbox.h
trunk/php/luasandbox/tests/pcall.phpt
trunk/php/luasandbox/timer.c
Modified: trunk/php/luasandbox/luasandbox.c
===================================================================
--- trunk/php/luasandbox/luasandbox.c 2012-04-26 23:50:06 UTC (rev 115069)
+++ trunk/php/luasandbox/luasandbox.c 2012-04-27 01:24:20 UTC (rev 115070)
@@ -85,6 +85,9 @@
ZEND_ARG_INFO(0, emergency_limit)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(arginfo_luasandbox_getCPUUsage, 0)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_luasandbox_callFunction, 0)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, ...)
@@ -118,6 +121,7 @@
PHP_ME(LuaSandbox, setMemoryLimit, arginfo_luasandbox_setMemoryLimit, 0)
PHP_ME(LuaSandbox, getMemoryUsage, arginfo_luasandbox_getMemoryUsage, 0)
PHP_ME(LuaSandbox, setCPULimit, arginfo_luasandbox_setCPULimit, 0)
+ PHP_ME(LuaSandbox, getCPUUsage, arginfo_luasandbox_getCPUUsage, 0)
PHP_ME(LuaSandbox, callFunction, arginfo_luasandbox_callFunction, 0)
PHP_ME(LuaSandbox, registerLibrary, arginfo_luasandbox_registerLibrary,
0)
{NULL, NULL, NULL}
@@ -262,21 +266,24 @@
*/
static zend_object_value luasandbox_new(zend_class_entry *ce TSRMLS_DC)
{
- php_luasandbox_obj * intern;
+ php_luasandbox_obj * sandbox;
zend_object_value retval;
// Create the internal object
- intern = emalloc(sizeof(php_luasandbox_obj));
- memset(intern, 0, sizeof(php_luasandbox_obj));
- zend_object_std_init(&intern->std, ce TSRMLS_CC);
- intern->alloc.memory_limit = (size_t)-1;
+ sandbox = emalloc(sizeof(php_luasandbox_obj));
+ memset(sandbox, 0, sizeof(php_luasandbox_obj));
+ zend_object_std_init(&sandbox->std, ce TSRMLS_CC);
+ sandbox->alloc.memory_limit = (size_t)-1;
// Initialise the Lua state
- intern->state = luasandbox_newstate(intern);
+ sandbox->state = luasandbox_newstate(sandbox);
+ // Initialise the timer
+ luasandbox_timer_create(&sandbox->timer, sandbox);
+
// Put the object into the store
retval.handle = zend_objects_store_put(
- intern,
+ sandbox,
(zend_objects_store_dtor_t)zend_objects_destroy_object,
(zend_objects_free_object_storage_t)luasandbox_free_storage,
NULL TSRMLS_CC);
@@ -325,15 +332,14 @@
*/
static void luasandbox_free_storage(void *object TSRMLS_DC)
{
- php_luasandbox_obj * intern = (php_luasandbox_obj*)object;
+ php_luasandbox_obj * sandbox = (php_luasandbox_obj*)object;
- if (intern->state) {
- luasandbox_alloc_delete_state(&intern->alloc, intern->state);
- intern->state = NULL;
-
- intern->state = NULL;
+ luasandbox_timer_stop(&sandbox->timer);
+ if (sandbox->state) {
+ luasandbox_alloc_delete_state(&sandbox->alloc, sandbox->state);
+ sandbox->state = NULL;
}
- zend_object_std_dtor(&intern->std);
+ zend_object_std_dtor(&sandbox->std);
efree(object);
}
/* }}} */
@@ -657,9 +663,9 @@
/** {{{ proto void LuaSandbox::setCPULimit(mixed normal_limit, mixed
emergency_limit = false)
*
- * Set the limit of CPU time (user+system) for LuaSandboxFunction::call()
- * calls. There are two time limits, which are both specified in seconds. Set
- * a time limit to false to disable it.
+ * Set the limit of CPU time (user+system) for all LuaSandboxFunction::call()
+ * calls against this LuaSandbox instance. There are two time limits, which
+ * are both specified in seconds. Set a time limit to false to disable it.
*
* When the "normal" time limit expires, a flag will be set which causes
* a LuaSandboxError exception to be thrown when the currently-running Lua
@@ -671,6 +677,9 @@
* running, the Lua state is destroyed and then recreated with an empty state.
* Any LuaSandboxFunction objects which referred to the old state will stop
* working. A LuaSandboxEmergencyTimeout exception is thrown.
+ *
+ * Setting the time limit from a callback while Lua is running causes the timer
+ * to be reset, or started if it was not already running.
*/
PHP_METHOD(LuaSandbox, setCPULimit)
{
@@ -679,6 +688,9 @@
php_luasandbox_obj * sandbox = (php_luasandbox_obj*)
zend_object_store_get_object(getThis() TSRMLS_CC);
+ struct timespec normal = {0, 0};
+ struct timespec emergency = {0, 0};
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z",
&zpp_normal, &zpp_emergency) == FAILURE)
{
@@ -696,7 +708,7 @@
convert_to_double_ex(zpp_normal);
}
if (Z_TYPE_PP(zpp_normal) == IS_DOUBLE) {
- luasandbox_set_timespec(&sandbox->cpu_normal_limit,
Z_DVAL_PP(zpp_normal));
+ luasandbox_set_timespec(&normal, Z_DVAL_PP(zpp_normal));
sandbox->is_cpu_limited = 1;
} else {
sandbox->is_cpu_limited = 0;
@@ -707,20 +719,18 @@
|| (Z_TYPE_PP(zpp_emergency) == IS_BOOL &&
Z_BVAL_PP(zpp_emergency) == 0))
{
// No emergency limit
- sandbox->cpu_emergency_limit.tv_sec = 0;
- sandbox->cpu_emergency_limit.tv_nsec = 0;
} else {
convert_scalar_to_number_ex(zpp_emergency);
if (Z_TYPE_PP(zpp_emergency) == IS_LONG) {
convert_to_double_ex(zpp_emergency);
}
if (Z_TYPE_PP(zpp_normal) == IS_DOUBLE) {
- luasandbox_set_timespec(&sandbox->cpu_emergency_limit,
Z_DVAL_PP(zpp_emergency));
- } else {
- sandbox->cpu_emergency_limit.tv_sec = 0;
- sandbox->cpu_emergency_limit.tv_nsec = 0;
+ luasandbox_set_timespec(&emergency,
Z_DVAL_PP(zpp_emergency));
}
}
+
+ // Set the timer
+ luasandbox_timer_set_limits(&sandbox->timer, &normal, &emergency);
}
/* }}} */
@@ -747,6 +757,26 @@
/* }}} */
+/** {{{ proto float LuaSandbox::getCPUUsage()
+ *
+ * Get the amount of CPU used by this LuaSandbox instance, including any PHP
+ * functions called by Lua.
+ */
+PHP_METHOD(LuaSandbox, getCPUUsage)
+{
+ struct timespec ts;
+ php_luasandbox_obj * sandbox = (php_luasandbox_obj*)
+ zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ luasandbox_timer_get_usage(&sandbox->timer, &ts);
+ RETURN_DOUBLE(ts.tv_sec + 1e-9 * ts.tv_nsec);
+}
+/* }}} */
+
/** {{{ LuaSandbox::getMemoryUsage */
PHP_METHOD(LuaSandbox, getMemoryUsage)
{
@@ -915,8 +945,7 @@
// Keep track of the stack index where the return values will appear
int retIndex = origTop + 2;
int status;
- int cpu_limited = 0;
- luasandbox_timer_set t;
+ int timer_started = 0;
int i, numResults;
zval * old_zval;
@@ -945,13 +974,17 @@
}
// Initialise the CPU limit timer
- if (!sandbox->in_lua && sandbox->is_cpu_limited) {
- cpu_limited = 1;
+ if (!sandbox->in_lua) {
+ if (luasandbox_timer_is_expired(&sandbox->timer)) {
+ zend_throw_exception(luasandboxtimeouterror_ce,
luasandbox_timeout_message, LUA_ERRRUN);
+ lua_settop(L, origTop - 1);
+ RETURN_FALSE;
+ }
+ timer_started = 1;
if (!LUASANDBOX_G(signal_handler_installed)) {
luasandbox_timer_install_handler(&LUASANDBOX_G(old_handler));
}
- luasandbox_timer_start(&t, sandbox, &sandbox->cpu_normal_limit,
- &sandbox->cpu_emergency_limit);
+ luasandbox_timer_start(&sandbox->timer);
}
// Save the current zval for later use in luasandbox_call_php. Restore
it
@@ -966,8 +999,8 @@
sandbox->current_zval = old_zval;
// Stop the timer
- if (cpu_limited) {
- luasandbox_timer_stop(&t);
+ if (timer_started) {
+ luasandbox_timer_stop(&sandbox->timer);
}
if (sandbox->emergency_timed_out) {
luasandbox_handle_emergency_timeout(sandbox);
Modified: trunk/php/luasandbox/luasandbox_timer.h
===================================================================
--- trunk/php/luasandbox/luasandbox_timer.h 2012-04-26 23:50:06 UTC (rev
115069)
+++ trunk/php/luasandbox/luasandbox_timer.h 2012-04-27 01:24:20 UTC (rev
115070)
@@ -15,9 +15,11 @@
#define LUASANDBOX_SIGNAL SIGUSR2
#endif
+struct _php_luasandbox_obj;
+
typedef struct {
int emergency;
- php_luasandbox_obj * sandbox;
+ struct _php_luasandbox_obj * sandbox;
} luasandbox_timer_callback_data;
typedef struct {
@@ -28,30 +30,35 @@
typedef struct {
luasandbox_timer normal_timer;
luasandbox_timer emergency_timer;
- int use_emergency;
- php_luasandbox_obj * sandbox;
+ struct timespec normal_limit, normal_remaining;
+ struct timespec emergency_limit, emergency_remaining;
+ struct timespec usage_start, usage;
+ struct _php_luasandbox_obj * sandbox;
+ int is_running;
+ int normal_running;
+ int emergency_running;
} luasandbox_timer_set;
-#else
+#else /*CLOCK_REALTIME*/
#define LUASANDBOX_NO_CLOCK
typedef struct {} luasandbox_timer;
typedef struct {} luasandbox_timer_set;
-void timer_settime();
-void timer_delete();
-void timer_create();
-#endif
+#endif /*CLOCK_REALTIME*/
void luasandbox_timer_install_handler(struct sigaction * oldact);
void luasandbox_timer_remove_handler(struct sigaction * oldact);
-void luasandbox_timer_start(luasandbox_timer_set * lts,
- php_luasandbox_obj * sandbox,
- struct timespec * normal_timeout,
+void luasandbox_timer_create(luasandbox_timer_set * lts, struct
_php_luasandbox_obj * sandbox);
+void luasandbox_timer_set_limits(luasandbox_timer_set * lts,
+ struct timespec * normal_timeout,
struct timespec * emergency_timeout);
+void luasandbox_timer_start(luasandbox_timer_set * lts);
void luasandbox_timer_stop(luasandbox_timer_set * lts);
+void luasandbox_timer_get_usage(luasandbox_timer_set * lts, struct timespec *
ts);
+void luasandbox_timer_timeout_error(lua_State *L);
+int luasandbox_timer_is_expired(luasandbox_timer_set * lts);
-
-#endif
+#endif /*LUASANDBOX_TIMER_H*/
Modified: trunk/php/luasandbox/php_luasandbox.h
===================================================================
--- trunk/php/luasandbox/php_luasandbox.h 2012-04-26 23:50:06 UTC (rev
115069)
+++ trunk/php/luasandbox/php_luasandbox.h 2012-04-27 01:24:20 UTC (rev
115070)
@@ -4,6 +4,7 @@
#include <lua.h>
#include <signal.h>
+#include "luasandbox_timer.h"
/* alloc.c */
@@ -47,6 +48,7 @@
PHP_METHOD(LuaSandbox, setMemoryLimit);
PHP_METHOD(LuaSandbox, getMemoryUsage);
PHP_METHOD(LuaSandbox, setCPULimit);
+PHP_METHOD(LuaSandbox, getCPUUsage);
PHP_METHOD(LuaSandbox, callFunction);
PHP_METHOD(LuaSandbox, registerLibrary);
@@ -76,8 +78,7 @@
volatile int timed_out;
volatile int emergency_timed_out;
int is_cpu_limited;
- struct timespec cpu_normal_limit;
- struct timespec cpu_emergency_limit;
+ luasandbox_timer_set timer;
int function_index;
unsigned int random_seed;
};
@@ -92,7 +93,6 @@
php_luasandbox_obj * luasandbox_get_php_obj(lua_State * L);
-void luasandbox_timer_timeout_error(lua_State *L);
/** {{{ luasandbox_enter_php
*
Modified: trunk/php/luasandbox/tests/pcall.phpt
===================================================================
--- trunk/php/luasandbox/tests/pcall.phpt 2012-04-26 23:50:06 UTC (rev
115069)
+++ trunk/php/luasandbox/tests/pcall.phpt 2012-04-27 01:24:20 UTC (rev
115070)
@@ -2,7 +2,6 @@
pcall() catching various errors
--FILE--
<?php
-$sandbox = new LuaSandbox;
$lua = <<<LUA
function pcall_test(f)
local status, msg
@@ -24,12 +23,13 @@
'Out of memory' => 'string.rep("x", 1000000)'
);
-$sandbox->loadString( $lua )->call();
-$sandbox->setCPULimit( 0.25 );
-$sandbox->setMemoryLimit( 100000 );
foreach ( $tests as $desc => $code ) {
echo "$desc: ";
+ $sandbox = new LuaSandbox;
+ $sandbox->loadString( $lua )->call();
+ $sandbox->setCPULimit( 0.25 );
+ $sandbox->setMemoryLimit( 100000 );
try {
print implode("\n",
$sandbox->callFunction( 'pcall_test',
$sandbox->loadString( $code ) ) ) . "\n";
Modified: trunk/php/luasandbox/timer.c
===================================================================
--- trunk/php/luasandbox/timer.c 2012-04-26 23:50:06 UTC (rev 115069)
+++ trunk/php/luasandbox/timer.c 2012-04-27 01:24:20 UTC (rev 115070)
@@ -11,28 +11,72 @@
#include "php_luasandbox.h"
#include "luasandbox_timer.h"
+char luasandbox_timeout_message[] = "The maximum execution time for this
script was exceeded";
+
#ifdef LUASANDBOX_NO_CLOCK
void luasandbox_timer_install_handler(struct sigaction * oldact) {}
void luasandbox_timer_remove_handler(struct sigaction * oldact) {}
-void luasandbox_timer_start(luasandbox_timer_set * lts,
- php_luasandbox_obj * sandbox,
- struct timespec * normal_timeout,
+void luasandbox_timer_create(luasandbox_timer_set * lts,
+ php_luasandbox_obj * sandbox) {}
+void luasandbox_timer_set_limits(luasandbox_timer_set * lts,
+ struct timespec * normal_timeout,
struct timespec * emergency_timeout) {}
+void luasandbox_timer_start(luasandbox_timer_set * lts) {}
void luasandbox_timer_stop(luasandbox_timer_set * lts) {}
+
+void luasandbox_timer_get_usage(luasandbox_timer_set * lts, struct timespec *
ts) {
+ ts->tv_sec = ts->tv_nsec = 0;
+}
void luasandbox_timer_timeout_error(lua_State *L) {}
-char luasandbox_timeout_message[];
+int luasandbox_is_expired(luasandbox_timer_set * lts) {
+ return 0;
+}
+
#else
static void luasandbox_timer_handle(int signo, siginfo_t * info, void *
context);
-static void luasandbox_timer_create(luasandbox_timer * lt, php_luasandbox_obj
* sandbox,
+static void luasandbox_timer_create_one(luasandbox_timer * lt,
php_luasandbox_obj * sandbox,
int emergency);
static void luasandbox_timer_timeout_hook(lua_State *L, lua_Debug *ar);
-static void luasandbox_timer_settime(luasandbox_timer * lt, struct timespec *
ts);
+static void luasandbox_timer_set_one_time(luasandbox_timer * lt, struct
timespec * ts);
+static void luasandbox_timer_stop_one(luasandbox_timer * lt, struct timespec *
remaining);
+static void luasandbox_update_usage(luasandbox_timer_set * lts);
-char luasandbox_timeout_message[] = "The maximum execution time for this
script was exceeded";
+static inline void luasandbox_timer_zero(struct timespec * ts)
+{
+ ts->tv_sec = ts->tv_nsec = 0;
+}
+static inline int luasandbox_timer_is_zero(struct timespec * ts)
+{
+ return ts->tv_sec == 0 && ts->tv_nsec == 0;
+}
+
+static inline void luasandbox_timer_subtract(
+ struct timespec * a, const struct timespec * b)
+{
+ a->tv_sec -= b->tv_sec;
+ if (a->tv_nsec < b->tv_nsec) {
+ a->tv_sec--;
+ a->tv_nsec += 1000000000L - b->tv_nsec;
+ } else {
+ a->tv_nsec -= b->tv_nsec;
+ }
+}
+
+static inline void luasandbox_timer_add(
+ struct timespec * a, const struct timespec * b)
+{
+ a->tv_sec += b->tv_sec;
+ a->tv_nsec += b->tv_nsec;
+ if (a->tv_nsec > 1000000000L) {
+ a->tv_nsec -= 1000000000L;
+ a->tv_sec++;
+ }
+}
+
void luasandbox_timer_install_handler(struct sigaction * oldact)
{
struct sigaction newact;
@@ -100,26 +144,64 @@
lua_error(L);
}
-void luasandbox_timer_start(luasandbox_timer_set * lts,
- php_luasandbox_obj * sandbox,
- struct timespec * normal_timeout,
+void luasandbox_timer_create(luasandbox_timer_set * lts, php_luasandbox_obj *
sandbox)
+{
+ luasandbox_timer_zero(<s->usage);
+ luasandbox_timer_zero(<s->normal_limit);
+ luasandbox_timer_zero(<s->normal_remaining);
+ luasandbox_timer_zero(<s->emergency_limit);
+ luasandbox_timer_zero(<s->emergency_remaining);
+ lts->is_running = 0;
+ lts->normal_running = 0;
+ lts->emergency_running = 0;
+ lts->sandbox = sandbox;
+}
+
+void luasandbox_timer_set_limits(luasandbox_timer_set * lts,
+ struct timespec * normal_timeout,
struct timespec * emergency_timeout)
{
- // Create normal timer
- luasandbox_timer_create(<s->normal_timer, sandbox, 0);
- luasandbox_timer_settime(<s->normal_timer, normal_timeout);
+ int was_running = 0;
+ if (lts->is_running) {
+ was_running = 1;
+ lusandbox_timer_stop(lts);
+ }
+ lts->normal_remaining = lts->normal_limit = *normal_timeout;
+ lts->emergency_remaining = lts->emergency_limit = *emergency_timeout;
+ if (was_running) {
+ luasandbox_timer_start(lts);
+ }
+}
+void luasandbox_timer_start(luasandbox_timer_set * lts)
+{
+ if (lts->is_running) {
+ // Already running
+ return;
+ }
+ lts->is_running = 1;
+ // Initialise usage timer
+ clock_gettime(LUASANDBOX_CLOCK_ID, <s->usage_start);
+
+ // Create normal timer if requested
+ if (!luasandbox_timer_is_zero(<s->normal_remaining)) {
+ lts->normal_running = 1;
+ luasandbox_timer_create_one(<s->normal_timer, lts->sandbox,
0);
+ luasandbox_timer_set_one_time(<s->normal_timer,
<s->normal_remaining);
+ } else {
+ lts->normal_running = 0;
+ }
// Create emergency timer if requested
- if (emergency_timeout->tv_sec || emergency_timeout->tv_nsec) {
- lts->use_emergency = 1;
- luasandbox_timer_create(<s->emergency_timer, sandbox, 1);
- luasandbox_timer_settime(<s->emergency_timer,
emergency_timeout);
+ if (!luasandbox_timer_is_zero(<s->emergency_remaining)) {
+ lts->emergency_running = 1;
+ luasandbox_timer_create_one(<s->emergency_timer,
lts->sandbox, 1);
+ luasandbox_timer_set_one_time(<s->emergency_timer,
<s->emergency_remaining);
} else {
- lts->use_emergency = 0;
+ lts->emergency_running = 0;
}
}
-static void luasandbox_timer_create(luasandbox_timer * lt, php_luasandbox_obj
* sandbox,
+static void luasandbox_timer_create_one(luasandbox_timer * lt,
php_luasandbox_obj * sandbox,
int emergency)
{
struct sigevent ev;
@@ -134,25 +216,84 @@
timer_create(LUASANDBOX_CLOCK_ID, &ev, <->timer);
}
-static void luasandbox_timer_settime(luasandbox_timer * lt, struct timespec *
ts)
+static void luasandbox_timer_set_one_time(luasandbox_timer * lt, struct
timespec * ts)
{
struct itimerspec its;
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 0;
+ luasandbox_timer_zero(&its.it_interval);
its.it_value = *ts;
timer_settime(lt->timer, 0, &its, NULL);
}
+
void luasandbox_timer_stop(luasandbox_timer_set * lts)
{
- struct timespec zero = {0, 0};
- if (lts->use_emergency) {
- luasandbox_timer_settime(<s->emergency_timer, &zero);
- timer_delete(lts->emergency_timer.timer);
+ struct timespec usage;
+
+ if (lts->is_running) {
+ lts->is_running = 0;
+ } else {
+ return;
}
- luasandbox_timer_settime(<s->normal_timer, &zero);
- timer_delete(lts->normal_timer.timer);
+ // Stop the interval timers and save the time remaining
+ if (lts->emergency_running) {
+ luasandbox_timer_stop_one(<s->emergency_timer,
<s->emergency_remaining);
+ lts->emergency_running = 0;
+ }
+ if (lts->normal_running) {
+ luasandbox_timer_stop_one(<s->normal_timer,
<s->normal_remaining);
+ lts->normal_running = 0;
+ }
+
+ // Update the usage
+ luasandbox_update_usage(lts);
+ clock_gettime(LUASANDBOX_CLOCK_ID, &usage);
+ luasandbox_timer_subtract(&usage, <s->usage_start);
+ luasandbox_timer_add(<s->usage, &usage);
}
+
+static void luasandbox_timer_stop_one(luasandbox_timer * lt, struct timespec *
remaining)
+{
+ static struct timespec zero = {0, 0};
+ struct itimerspec its;
+ timer_gettime(lt->timer, &its);
+ remaining->tv_sec = its.it_value.tv_sec;
+ remaining->tv_nsec = its.it_value.tv_nsec;
+ luasandbox_timer_set_one_time(lt, &zero);
+ timer_delete(lt->timer);
+}
+
+void luasandbox_timer_get_usage(luasandbox_timer_set * lts, struct timespec *
ts)
+{
+ if (lts->is_running) {
+ luasandbox_update_usage(lts);
+ }
+ *ts = lts->usage;
+}
+
+int luasandbox_timer_is_expired(luasandbox_timer_set * lts)
+{
+ if (!luasandbox_timer_is_zero(<s->normal_limit)) {
+ if (luasandbox_timer_is_zero(<s->normal_remaining)) {
+ return 1;
+ }
+ }
+ if (!luasandbox_timer_is_zero(<s->emergency_limit)) {
+ if (luasandbox_timer_is_zero(<s->emergency_remaining)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void luasandbox_update_usage(luasandbox_timer_set * lts)
+{
+ struct timespec current, usage;
+ clock_gettime(LUASANDBOX_CLOCK_ID, ¤t);
+ usage = current;
+ luasandbox_timer_subtract(&usage, <s->usage_start);
+ luasandbox_timer_add(<s->usage, &usage);
+ lts->usage_start = current;
+}
#endif
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs