Tomas Pospisek
3/5/2007 6:34:00 PM
Quoting Gary Wright <gwtmp01@mac.com>:
> On Mar 5, 2007, at 9:03 AM, Tomas Pospisek wrote:
> > With the current "broken" semantics, that would work just right,
> > since with
> > the current implementation sleep() time would increase/decrease in
> > parallel
> > with the "sysadmin" changing the system time with "date -s" or
> > similar.
>
> Any serious sysadmin will use a NTP based configuration to manage the
> time on their system. Time adjustments will slow or speed up the clock
> but won't cause it to skip ahead or back.
>
> Your proposal seems like a lot of effort to go through and it
> certainly won't prevent a sysadmin from just issuing "kill -9 pid". My
> point is that you'll never be able to write a program that successfully
> operates in the presence of a malicious or ignorant superuser.
>
> As a compromise, maybe a scheme could be devised to *detect* when the
> clock has been readjusted and to cause an exception. I'm not sure if that
> would be helpful or useful, but it is probably easier than trying to craft a
> portable user-space scheduler that is independent of the system clock
> (especially without vendor support via POSIX or other industry
> standard).
That means, to be precise, that ruby is "serious admin proof" only and won't
"correcly" survive some noob that actually dares to use "date -s" on his system
(or - for that matter - doubleclicks on the clock on the right on the bottom of
the screen) at the wrong instant...
And no, the effort to fix it is not so big. Here's the patch for the "do it
right" approach:
-------------------------------------------------------
--- eval.c.orig 2007-03-05 14:51:31.000000000 +0100
+++ eval.c 2007-03-05 18:12:42.823969936 +0100
@@ -9858,9 +9858,15 @@
static double
timeofday()
{
+#ifdef _POSIX_MONOTONIC_CLOCK
+ struct timespec tv;
+ clock_gettime(CLOCK_MONOTONIC, &tv );
+ return (double)tv.tv_sec + (double)tv.tv_nsec * 1e-9;
+#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
+#endif
}
#define STACK(addr) (th->stk_pos<(VALUE*)(addr) &&
(VALUE*)(addr)<th->stk_pos+th->stk_len)
-------------------------------------------------------
Some comments about this patch:
* it survives the unit tests in the test/ directory
* it actually does fix the issue (changing the system time while sleeping)
* clock_gettime requires linking with librt, so this needs to be taken care of
in configure.in
* for some reason unknown to me I had to use gcc > 3.5.5 to link it, maybe
I'd have needed to "make clean && configure ..." - I don't know.
* it only takes care of the problem on systems that have
_POSIX_MONOTONIC_CLOCK. Other systems either need to provide their own ways
or live with the old, "buggy" behaveour or can implement the other suggested
fix namely to "fix the worst case" through not letting the "remaining_time"
ever increase.
* it'd be nice to change the function name timeofday() to something more
neutral like getcurrenttime() or such, to disambiguate the name from the
POSIX functions
Greets,
*t
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.