[M3devel] time conversion re-entrancy issues
Tony Hosking
hosking at cs.purdue.edu
Tue Nov 13 17:56:05 CET 2007
On Nov 13, 2007, at 2:06 AM, Mika Nystrom wrote:
> Hello everyone,
>
> I just ran into this on the program I'm developing. It's a crash
> in my
> own code, but I believe that the conversion routines in Date.i3 aren't
> immune to it either...
>
>
> Program received signal SIGBUS, Bus error.
> ThreadPosix.UTimeNow (_result=RECORD tv_sec = 138291084; tv_usec =
> 1747444928;
> END) at ThreadPosix.m3:126
> ThreadPosix.m3:126: No such file or directory.
> (gdb) where
> #0 ThreadPosix.UTimeNow (_result=RECORD tv_sec = 138291084;
> tv_usec = 1747444928; END) at ThreadPosix.m3:126
> #1 16_8190658 in ThreadPosix.switch_thread () at ThreadPosix.m3:772
> #2 16_bfbfff94 in ?? ()
> #3 16_6827e4c0 in tzsetwall ()
> #4 16_6827e789 in localtime_r ()
> #5 16_81354ac in TZ.Localtime (t=16_832c3ec, timeArg=1194934056,
> _result=RECORD year = 0; month = Jan;
> day = <subrange value 0 out of range [1..31]>; hour = 0; minute
> = 0;
> second = 0; offset = 2; zone = <Error reading address 16_0:
> Bad address>;
> weekDay = <enum value 234 out of range [0..6]>; END) at TZ.m3:47
> #6 16_8135d0b in TZ.FormatSubsecond (tz=16_832c3ec,
> t=1194934056.6984761,
> prec=3, simplified=TRUE) at SafeTZ.m3:23
>
> What's going on is that I'm converting a Time.T to a Date.T using
> my own conversion routine, which eventually calls the Unix
> localtime_r function (same procedure, done a bit more elaborately,
> as in the standard implementation of Date.FromTime).
>
> The problem is that localtime apparently under certain circumstances
> can call tzsetwall, which can take a while to run, as it involves
> reading
> timezone info from /usr/share/zoneinfo. My diagnosis is that the
> thread
> doing the conversion yielded, and then something in ThreadPosix
> (OK this is an old version, but the current version works the same)
> calls gettimeofday. And apparently gettimeofday isn't re-entrant
> w.r.t.
> tzsetwall.
>
> Is there a portable (i.e., across M3 versions) way of stopping all
> threadswitching activity while a call into some nasty C code is
> proceeding? I don't see how one can avoid it here...
Not really a portable way to do it. SchedulerPosix.DisableSwitching
works when using ThreadPosix. For ThreadPThread
SchedulerPosix.DisableSwitching is a no-op but the libraries should
be thread-safe anyway so it probably works there too. What you
really need is a lock somewhere.
More information about the M3devel
mailing list