GNOME Bugzilla – Bug 644761
Problems with g_time_zone_new_local()
Last modified: 2011-04-07 21:24:49 UTC
There are two problems here 1. The GTimeZone returned by g_time_zone_new_local() is currently a singleton but when the last reference is released it is destroyed. 2. The GTimeZone returned by g_time_zone_new_local() should somehow update itself as /etc/localtime changes. Problem 1. means that an UI displaying a clock ("the clock in the UI"), updating every second, will do a syscall every second. This performance impact might not be acceptable (then again, all modern distros are using noatime so at least there is no disk spin-up). Because of problem 2, the clock in the UI is not updated for timezone changes if another random caller is holding a reference to the GTimeZone returned by g_time_zone_new_local(). This is probably not acceptable. One suggested fix is to - Never destroy the GTimeZone for the local time zone once created; and - Somehow monitor the /etc/localtime file This issue came up while fixing bug 635840.
<davidz> desrt: hey - why does GTimeZone Just Work(tm) with timezone changes? (see above discussion) <davidz> desrt: e.g. when /etc/localtime is either a symlink that is changed or when it's atomically replaced <desrt> davidz: can you give me a quick summary? <davidz> desrt: owen and I are curious why GTimeZone just keeps working when the timezone is changed... so we have a GTimeZone object around that keeps a GMappedFile around for /etc/localtime, right? <owen> desrt: basically, GMappedFile on /etc/localtime, how does it work that it follows the new data if /etc/localtime is resymlinked? <desrt> davidz: very curious. <davidz> desrt: which is fine and all.. having the mapped file for /etc/localtime around... we are just curious why the mapping changes when /etc/localtime is changed (it can change in the two ways mentioned above) <desrt> i don't remember what i did <owen> desrt: does it surprise you that a GMappedFile opened on a symlink updates when the symlink changes? It surprised me <desrt> owen: yes. i'm surprised. i also don't remember inserting logic to deal with this. but maybe i did. <owen> (assuming that's actually happening. Testing seems to indicate that, but you know, testing could always be going wrong) <davidz> I didn't find any logic for this... <owen> desrt: there's no logic in GMappedFile or gtimezone that I saw <desrt> owen: ya. i'm forced to conclude that you guys are actually insane <davidz> well, the code is all on master now.. so just run the latest gnome-shell and resymlink /etc/localtime as you please :-) <desrt> i suspect you may be creating/destroying GTimeZone instances quite often iirc, once you drop your last use of a GTimeZone, it falls out of the cache it looks deliciously non-threadsafe.... maybe i should fix that oh no. there's a lock. nvm. <desrt> as it turns out, the behaviour that you get from using local timezones with respect to changes to the TZ environment variable or /etc/localtime is somewhat non-deterministic <davidz> ah, wait it actually does keep opening /etc/localtime the shell every second <desrt> depending on if someone else is holding a reference on the local timezone the file will either be held open or continuously reopened <owen> desrt: confirmed <owen> davidz: so, this doesn't work - we can't have code that works as long as nobody happens to be keeping a GDateTime around <desrt> i'm open to firming up that behaviour one way or another if anyone has a good proposal <owen> desrt: I believe that glib needs to pick up timezone changes for newly created GDateTime objects without any application intervention <desrt> yes. probably. the question is if existing ones should also change <owen> I'm agnostic as to whether if you keep a g_date_time_new_local() around whether it "fossilizes" at the created timezone or not <desrt> i think the immutable nature of GDateTime argues for the fossilisation <davidz> owen: agreed.. and glib should probably use a singleton for the local timezone instead of calling open("/etc/localtime") all the time <desrt> davidz: it does use a singleton <davidz> oh well.. I mean, a singleton that doesn't die <desrt> yes. that's another story. <davidz> when the last reference goes away... <desrt> the local timezone could be treated in a special way <davidz> desrt: right.. could and probably should desrt, owen: want to file the bug? <owen> desrt: My general feeling is that if it's cheap, we shouldn't fossilize <desrt> okay. i'll think about it owen: my problem is that people tend to use GDateTime by calling a bunch of accessor functions on it <owen> desrt: since that's just going to mean app bugs - someone keeps a GDateTime aroudn in a treeview gpointer column and then woah, it doesn't update <sweeze> aday: ha, yeah read from owen's git log pointer. guess use case of "temp mute, and then restore to same volume level" isn't actually a common one <desrt> owen: imagine the timezone magically changes in the middle of one of those calls <owen> desrt: well, we don't have any mechanism for application sto get notified and repaint on timezone changes <desrt> owen: by your reasoning, we should also have a 'changed' signal on the immutable GDateTime so someone can tell the treeview that it needs to update? (not saying that's totally crazy, but it does seem a bit odd on first brush) * desrt needs to run out a moment -- back in 10 <owen> desrt: so there's lots of potential weirdness, but other than the performance problems of "how do we avoid calling some system call for every accessor" I don't worry too much about the non-atomicity of changing while an app is doing something <owen> desrt: anyways, I'm mostly agnostic. Though I think if we do fossilize, we should have a GDateTime function that creates a new local GDateTime from a UTC GDateTime and advise only keeping UTC GDateTime around in an app desrt: and at some point we do need to figure out how to signal timezone changes, or have a GDateTimeLabel that formats on every paint. But then still we need to signal repaint on timezone changes, since with a compositor apps can just not repaint <owen> The approach davidz is taking with the panel of just updating it every second may be OK for that, but it's clearly not OK for an app with a 1000 times in a tree view <owen> on the other hand, how often do you change your timezone?
Bug 644814 is for the shell using this (and doing other optimizations to avoid waking up once a second).
*** This bug has been marked as a duplicate of bug 644771 ***