Re: bugs regarding late g_thread_init() calls
Hi there, On Tue, 2007-01-02 at 14:34 +0100, Tim Janik wrote: since the very early inception of the glib threading system, the docs say ( http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html ): You must call g_thread_init() before executing any other GLib functions in a threaded GLib program. This doesn't appear in the gtk+-2.6 docs (cf. http://www.gtk.org/api/2.6/glib/glib-Threads.html ), indeed it arrived quite 'recently' [ in sluggish-ISV-months ] revision 1.50 date: 2005/05/20 17:15:37; author: matthiasc; state: Exp; lines: +8 -0 2005-05-20 Matthias Clasen [EMAIL PROTECTED] * glib/tmpl/threads.sgml: Add a paragraph about thread safety of GLib data structures. Which (I imagine) first shipped in glib-2.8.0 - August 2005; 18 months ago. Of course, the argument it was always like that is perhaps better, though Owen suggests it wasn't always :-) http://bugzilla.gnome.org/show_bug.cgi?id=331853 # (WONTFIX) Handle using gslice before g_thread_init() better Reading Tor's patch it appears (to uneducated me), to fix this for GSlice - and thus avoid rather a disruptive change. Having said that, I think Tor's patch could prolly be made somewhat simpler; by abandoning the main_thread_self variable, and just doing the g_private_set inside the _gslice_thread_init_nomessage call - indeed, if we were suitably 31337 we could transfer the old private value to the new threaded version; is this a complete 'fix' ? (and/or would it / does it work ? [ uncompiled, etc. ;-] ;-) --- glib/gslice.c (revision 5207) +++ glib/gslice.c (working copy) @@ -386,7 +386,11 @@ } if (!sys_page_size) g_slice_init_nomessage(); - private_thread_memory = g_private_new (private_thread_memory_cleanup); + { +GPrivate *tmem = g_private_new (private_thread_memory_cleanup); +g_private_set (tmem, private_thread_memory); +private_thread_memory = tmem; + } allocator-magazine_mutex = g_mutex_new(); allocator-slab_mutex = g_mutex_new(); if (allocator-config.debug_blocks) Of course, an early init for all gtk+ apps is a good solution that should catch most cases; but take pity on ORBit2 that can be used in a non-threaded scenario; and (AFAIR) likes to use glib routined to parse it's options at init time, one of which is turn-on-threading (or similar) ;-) HTH, Michael. -- [EMAIL PROTECTED] , Pseudo Engineer, itinerant idiot ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Michael Meeks writes: Of course, the argument it was always like that is perhaps better, though Owen suggests it wasn't always :-) Indeed it wasn't. GNOME programs have been calling tons of GLib functions before gnome_program_init() eventually called g_thread_init() for ages without ill effects, as far as I know. So, as much as I hate saying this, I think that it is too late now starting crashing if g_thread_init() is called too late. It's our own fault. When we introduced a requirement like that, we should have *enforced* it. In my opinion what needs to be done is this: GLib should normally always be threaded (behave as if g_thread_init(NULL) had been called at the very start of main()), and g_thread_init(NULL) will thus turn into a no-op. Then, for the benefits of those few apps that really are sure they won't ever create threads, introduce a new function: g_i_promise_no_threads(). This function, if called at all, should be called before calling any other GLib function. (And this time, check that the promise is held, and if it isn't, crash and burn.) --tml ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Hi Tim, On Thu, 2007-01-04 at 12:56 +0100, Tim Janik wrote: which is exactly the problem. *if* we support it, we need to *fully* do that, i.e. keep supporting it. Nah; there is no need to fully support it, merely behaving like we did in the past would be adequate for the legacy tail of people expecting the old behavior surely ? please use diff -up for posting patches. Hokay, I did 'svn diff' which appears not to like options on svn head. if (!sys_page_size) g_slice_init_nomessage(); - private_thread_memory = g_private_new (private_thread_memory_cleanup); + { +GPrivate *tmem = g_private_new (private_thread_memory_cleanup); +g_private_set (tmem, private_thread_memory); +private_thread_memory = tmem; + } unless you meant to call thread_memory_from_self() here, to initialize the main thread allocator eagerly, this change doesn't make too much sense. Ah - I did mention this was somewhat 31337 ? ;-) my thinking goes that if thread_memory_from_self is called -without- having inited threads then 'private_thread_memory' will be set to the ThreadMemory pointer: #define g_private_set(private_key, value) G_THREAD_CF (private_set, \ (void) (private_key = \ (GPrivate*) (value)), \ (private_key, value)) ergo we transfer it to the (new) thread private memory (NB. if unused, NULL is transfered), but I admit the behaviour is not at all obvious :-) [ perhaps a cast would make it clearer ? ;-] i.e., did you want to write this? Something like this would work too, perhaps be clearer. This leaks though: private_thread_memory = g_private_new (private_thread_memory_cleanup); ^^^ trampled on the old ThreadMemory... ThreadMemory *tmem = thread_memory_from_self(); g_private_set (private_thread_memory, tmem); .. i'm not sure we have to do the manual shuffling from Tor's patch at all though, i'd rather try to fix the g_private usage so it always does the right thing regardless of whether threading is initialized. Quite. Of course, an early init for all gtk+ apps is a good solution that should catch most cases; but take pity on ORBit2 that can be used in a non-threaded scenario; huh? does ORBit2 call gtk_init()? Nope; so we need a different solution. HTH, Michael. -- [EMAIL PROTECTED] , Pseudo Engineer, itinerant idiot ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
I am looking around and I am having trouble finding a single application that does this new (yes, new) required initialization right. Either... 1. Applications do not explicitly call g_thread_init and call gtk_init too late. 2. Applications call g_thread_init too late. 3. Applications call g_thread_init too early. Does anyone want to claim a case that is right for a non-trivial application? Something with a translated GUI. M. Note: if (!g_thread_supported ()) g_thread_init (NULL); bz! g_thread_supported called too early. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Morten Welinder wrote: I am looking around and I am having trouble finding a single application that does this new (yes, new) required initialization right. Either... 1. Applications do not explicitly call g_thread_init and call gtk_init too late. 2. Applications call g_thread_init too late. 3. Applications call g_thread_init too early. Does anyone want to claim a case that is right for a non-trivial application? Something with a translated GUI. Does this count: http://mooedit.sourceforge.net/hg/moo/?f=-1;file=medit/medit-app.opag line 259. I admit it wasn't the case before this stuff started, but it was like that with __WIN32__ defined :) Regards, Yevgen ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Thu, 4 Jan 2007, Yevgen Muntyan wrote: Morten Welinder wrote: I am looking around and I am having trouble finding a single application that does this new (yes, new) required initialization right. Either... 1. Applications do not explicitly call g_thread_init and call gtk_init too late. 2. Applications call g_thread_init too late. 3. Applications call g_thread_init too early. Does anyone want to claim a case that is right for a non-trivial application? Something with a translated GUI. Does this count: http://mooedit.sourceforge.net/hg/moo/?f=-1;file=medit/medit-app.opag line 259. if you call g_mem_set_vtable(), you have to call it before any other glib function, including g_thread_init(). otherwise the vtable allocator you're plugging won't get paired alloc/free calls and get messed up. if you're calling g_slice_set_config(), you don't know what you're doing, it's declared *internal* API. I admit it wasn't the case before this stuff started, but it was like that with __WIN32__ defined :) Regards, Yevgen --- ciaoTJ ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Tim Janik wrote: On Thu, 4 Jan 2007, Yevgen Muntyan wrote: Morten Welinder wrote: I am looking around and I am having trouble finding a single application that does this new (yes, new) required initialization right. Either... 1. Applications do not explicitly call g_thread_init and call gtk_init too late. 2. Applications call g_thread_init too late. 3. Applications call g_thread_init too early. Does anyone want to claim a case that is right for a non-trivial application? Something with a translated GUI. Does this count: http://mooedit.sourceforge.net/hg/moo/?f=-1;file=medit/medit-app.opag line 259. if you call g_mem_set_vtable(), you have to call it before any other glib function, including g_thread_init(). otherwise the vtable allocator you're plugging won't get paired alloc/free calls and get messed up. if you're calling g_slice_set_config(), you don't know what you're doing, it's declared *internal* API. You're right, if I am doing evil things, I'm screwed up. But I am not doing them [1]. Can I still have my cookie for a nice g_thread_init() user? Regards, Yevgen [1] Long story short, the code with g_set_memtable has *never* been called together with g_thread_init. I did use internal API in evil ways, but nobody have seen, I checked. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Morten Welinder wrote: Does this count: http://mooedit.sourceforge.net/hg/moo/?f=-1;file=medit/medit-app.opag line 259. There seems to be no translated GUI involved. And if there had been, that g_thread_init call would have been too early. GUI is translated, and program is non-trivial, and everything. setlocale must not be called after threads have been initialized, except to query the current locale. This is another thing. Is this correct? If yes, then are we all completely screwed? Regards, Yevgen ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
This is another thing. Is this correct? If yes, then are we all completely screwed? Certainly. Google threads setlocale unix and see. For example http://www.phy.ohiou.edu/cgi-bin/man-cgi.sol?setlocale+3C To change locale in a multi-thread application setlocale should be called prior to using any locale sensitive rou- tine. Using setlocale to query the current locale is safe and can be used anywhere in a multi-thread application. setlocale will happily dlclose code that another thread is running. Or worse. M. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Morten Welinder wrote: This is another thing. Is this correct? If yes, then are we all completely screwed? Certainly. Google threads setlocale unix and see. For example http://www.phy.ohiou.edu/cgi-bin/man-cgi.sol?setlocale+3C To change locale in a multi-thread application setlocale should be called prior to using any locale sensitive rou- tine. Using setlocale to query the current locale is safe and can be used anywhere in a multi-thread application. setlocale will happily dlclose code that another thread is running. Or worse. Um, non-thread-safe setlocale() is not a problem yet, since g_thread_init() doesn't create threads. Can g_thread_init() alone break when called before setlocale() ? E.g. I create threads inside gtk_main(), after gtk_init() which calls setlocale(); and I create threads after I call bindtextdomain() and whatnot. Am I good? Regards, Yevgen ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Michael Meeks wrote: Hi Tim, On Thu, 2007-01-04 at 12:56 +0100, Tim Janik wrote: which is exactly the problem. *if* we support it, we need to *fully* do that, i.e. keep supporting it. Nah; there is no need to fully support it, merely behaving like we did in the past would be adequate for the legacy tail of people expecting the old behavior surely ? please use diff -up for posting patches. Hokay, I did 'svn diff' which appears not to like options on svn head. Hi, You can do this 2 ways: 1. Run svn diff --diff-cmd=/usr/bin/diff -x -up 2. Follow the instructions on the Subversion migration page which points to this wiki: http://www.xenomai.org/index.php/Teaching_-p_to_svn_diff -- Regards, Martyn ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Thu, 2007-01-04 at 09:25 -0500, Morten Welinder wrote: Note: if (!g_thread_supported ()) g_thread_init (NULL); bz! g_thread_supported called too early. g_thread_supported is actually a macro. It's another name for g_threads_got_initialized basically. So the idiom above should be safe, right? -- Bye, -Torsten ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Torsten Schoenfeld wrote: if (!g_thread_supported ()) g_thread_init (NULL); bz! g_thread_supported called too early. g_thread_supported is actually a macro. It's another name for g_threads_got_initialized basically. So the idiom above should be safe, right? Just $.02, but does this mean that a programmer need to be an expert in the status of each symbol just to initialize a program properly? It seems to me that there is an evolution here from glib being a library that works readily without threads to one that usually assumes that threads are going to be initialized and probably used. I don't know what that means in terms of api, but it might help to explicitly note that this is a change. One more thing -- isn't there a binary compatibility issue here? If a program worked with 2.6, doesn't it need to work with new releases without recompilation in order for binary compatibility to be preserved? Cheers, John ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Wed, 3 Jan 2007, Gustavo J. A. M. Carneiro wrote: On Qua, 2007-01-03 at 00:57 +0100, Tim Janik wrote: On Tue, 2 Jan 2007, Gustavo J. A. M. Carneiro wrote: On Ter, 2007-01-02 at 14:34 +0100, Tim Janik wrote: hey all. since the very early inception of the glib threading system, the docs say ( http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html ): You must call g_thread_init() before executing any other GLib functions in a threaded GLib program. In PyGObject it is virtually impossible to guarantee that g_thread_init() gets called before using some other GLib APIs. At least not without changing the API. That's because g_thread_init() is called by the python function gobject.threads_init(), but you obviously can't call gobject.threads_init() without importing gobject first, and of course import gobject already calls some GLib APIs... This is a very tricky problem :| what glib APIs are you calling there and why couldn't g_thread_init() be the first glib function to call there? For instance, g_boxed_type_register_static and g_quark_from_static_string, probably others. We need to call these on python module initialization. We don't want to call g_thread_init() unless the programmer requests to, in order to not suffer threading support performance penalty, of course.. in the single threaded case, the overhead is negligible and in the multithreaded case you need g_thread_init() anyway. so you're best off with calling g_thread_init() right before g_type_init(). -- Gustavo J. A. M. Carneiro [EMAIL PROTECTED] [EMAIL PROTECTED] The universe is always one step beyond logic. --- ciaoTJ ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Some comments about this discussion, in more or less random order. * In the past, we've spent quite a bit of time making things work with late calls to g_thread_init() - allowing this usage has the big advantage that an application can use a library that uses threads internally without having to know about is. And that's really where threads are most useful in many cases: as internal implementation details of a library. But the way we've done it is never equivalent to a lazy call to g_thread_init() - that would require linking all apps to gthread and -lpthread, plus adding locking overhead internal to GLib. (I actually hadn't realized that late initialization worked, and was surprised a couple of years ago when Matthias pointed it out to me in the context of a patch to fix up a place which didn't work. I checked through the code and couldn't find any places that weren't OK, though I may have missed a few or we may have regressed. But if GSlice can be fixed, I think we could easily allow late initialization.) * Behdad's worry about another thread calling g_thread_init() while Pango is in the middle of an operation isn't an issue, because everybody (I think) agrees that g_thread_init() has to be called from the *main* thread, before you start threaded operation. * It does appear that we are pulling in pthread in any case for a standard GTK+ application these days, so perhaps it would be worth at least considering whether we wanted to make that a hard dependency; considerations: - What simplifications could we achieve with such a hard dependency? - The only use for libgthread is to avoid a hard pthread dependency; if we added such a dependency, would it make sense to make libgthread an empty dummy library? (it can't be quite empty on windows, since g_thread_init() has to stay in the same DLL) - Could g_thread_init() be removed entirely, by making the different subsystems lazily initialize themselves? What's the performance impact of the necessary GOnce usage for this? - What is the performance degradation when you link to -pthread? When you initialize GLib threading? But going in those directions is a fairly major project. * I really wouldn't worry about calls to g_thread_init() with anything other than the NULL as the parameter. Though we never formally deprecated the usage, there is a fairly warning about it in the docs: You should only call g_thread_init() with a non-%NULL parameter if you really know what you are doing. If we need to remove the functionality of that parameter, we can always claim that the callers didn't know what they were doing. :-) - Owen ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
* It does appear that we are pulling in pthread in any case for a standard GTK+ application these days, so perhaps it would be worth at least considering whether we wanted to make that a hard dependency; considerations: - What simplifications could we achieve with such a hard dependency? - The only use for libgthread is to avoid a hard pthread dependency; if we added such a dependency, would it make sense to make libgthread an empty dummy library? (it can't be quite empty on windows, since g_thread_init() has to stay in the same DLL) - Could g_thread_init() be removed entirely, by making the different subsystems lazily initialize themselves? What's the performance impact of the necessary GOnce usage for this? - What is the performance degradation when you link to -pthread? On many unix systems, linking with -lpthread will replace many libc calls (e.g. read, write, ...) by thread-safe versions, which are heavier (extra use of locks). Arno ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Tim Janik wrote: hey all. Hi, since the very early inception of the glib threading system, the docs say ( http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html ): You must call g_thread_init() before executing any other GLib functions in a threaded GLib program. multiple code portions rely on that, one such example is the GSlice code. i've thusly added a warning to GSlice code to catch cases where applications are calling g_thread_init() wrongly and as a consequence mess up GSlice state. this tunred out to actually be relevant in a significant number of apps, related bug reportss are: http://bugzilla.gnome.org/show_bug.cgi?id=331853 # (WONTFIX) Handle using gslice before g_thread_init() better http://bugzilla.gnome.org/show_bug.cgi?id=343490 # (FIXED) gnome_program_init() causes g_thread_init() to be called too late http://bugzilla.gnome.org/show_bug.cgi?id=391278 # (OPEN) gst programmes don't call g_thread_init early enough it has been claimed in a number of places that adding the above warning is breaking glib ABI. this is not the case, because the requirement has always been there, it just wasn't as strictly enforced. possible alternatives also have been suggested and i'll briefly sum them up: 1) GLib should auto-initialize the threading layer by calling g_thread_init (NULL) internally on demand. - this breaks the existing API where a custom threading function vtable can be specified as argument to g_thread_init(). allthough in practice, most programs will only want g_thread_init (NULL) initialization these days (the need for plugging a threading vtable was much higher in the late nineties when most systems didn't provide the same POSIX thread API). I think if you are going to use your own threading implementation, it should be something that you initialise the library with, if not, glib should fall back to the defaults. - there is no single glib internal entry point which could perform automated thread system initialization. and adding such initialisation code to 1000+ exported glib symbols would be grossly excessive. Yes, quite problematic but I think of those 1000+ exported symbols I wonder how many really need threading initialised before being used. 2) Auto-initialize via g_thread_init (NULL) in gnome_init(). + this has already been done for newer GNOME libs, see: http://bugzilla.gnome.org/show_bug.cgi?id=343490 This is my idea of a temporary solution. It doesn't really address the issue properly. 3) Auto-initialize with g_thread_init upon gtk_init + similar to gnome_init, gtk_init() could call: if (!g_threads_got_initialized) g_thread_init (NULL); this is not expected to be a problem for Gtk+ applications these days, and will fix too-late threading system initialization which is currently performed by file system backends of the new Gtk+ file selector. Again, this feels more like an after thought and not really the ideal solution here. 4) Patch up GSlice and other code to cope with late g_thread_init() calls + bug #331853 investigates this to some extend for GSlice, and it's probably possible, but requires significant implementation work. - however, other glib threading initialization portions still need to be evaluated wrg to supporting late g_thread_init() and may require more work. - even if it could be wokred out for all of the current glib systems, we can't be sure to be able to support arbitrarily late g_thread_init() calls in the future. at this point, i don't think (4) really has to be investigated/implemented, and i don't see spare resources for it anyway. however i'd like to propose the implementation of (3) to ease fixing of most non-gnome gtk applications. I think the question that needs answering first is: What in glib requires g_thread_init() to be called first? With my relatively limited experience of glib, all I can think of is: - gasyncqueue - gmain - gthread - gthreadpool - gslice - gtimer If it is a small portion of the code (i.e. just the few modules listed (above) then perhaps it should be initialised on demand. However, if it is needed in a lot of places and/or the impact of calling g_thread_init() is relatively minor anyway, then perhaps a g_init() function is needed which we expect users to call first (like gtk_init()) I would probably vote for initialising on demand. -- Regards, Martyn ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Tue, 2 Jan 2007, Martyn Russell wrote: Tim Janik wrote: 2) Auto-initialize via g_thread_init (NULL) in gnome_init(). + this has already been done for newer GNOME libs, see: http://bugzilla.gnome.org/show_bug.cgi?id=343490 This is my idea of a temporary solution. It doesn't really address the issue properly. it does, for all gnome programs. note that gnome_init() always used to call g_thread_init(), just not always early enough. 3) Auto-initialize with g_thread_init upon gtk_init + similar to gnome_init, gtk_init() could call: if (!g_threads_got_initialized) g_thread_init (NULL); this is not expected to be a problem for Gtk+ applications these days, and will fix too-late threading system initialization which is currently performed by file system backends of the new Gtk+ file selector. Again, this feels more like an after thought and not really the ideal solution here. well, at this point there is no compelling reason for a gtk program to not enable threading i think. especially since recent file chooser backends have been reported to dmand-init threading anway (which is clearly *always* too late). so fallback initialization of threading in gtk_init() and friends sounds like a non-intrusive change that gets rid of the problem for a lot of affected non-gnome apps. do you have any concrete reason to object this? 4) Patch up GSlice and other code to cope with late g_thread_init() calls + bug #331853 investigates this to some extend for GSlice, and it's probably possible, but requires significant implementation work. - however, other glib threading initialization portions still need to be evaluated wrg to supporting late g_thread_init() and may require more work. - even if it could be wokred out for all of the current glib systems, we can't be sure to be able to support arbitrarily late g_thread_init() calls in the future. at this point, i don't think (4) really has to be investigated/implemented, and i don't see spare resources for it anyway. however i'd like to propose the implementation of (3) to ease fixing of most non-gnome gtk applications. I think the question that needs answering first is: What in glib requires g_thread_init() to be called first? With my relatively limited experience of glib, all I can think of is: - gasyncqueue - gmain - gthread - gthreadpool - gslice - gtimer off-head, there's are also threading initializers in glog and gmem.c. i don't think this is a question properly phrased/answered though. nothing in glib *needs* threading per se, except for dedicated threading APIs (e.g. conditions, or async pools). the question is whether all the threading aware code (which spreads throughout all of glib, to make it thread-safe in general) can cope with *late* g_thread_init() calls, and development has never focussed on that. (we intentionally avoided that by demanding early calls to g_thread_init if it is called at all.) so unless you thoroughly audit all MT code, you can hardly be sure you've caught all required cases. If it is a small portion of the code (i.e. just the few modules listed (above) then perhaps it should be initialised on demand. that still bears the problem of figuring good entry points to demand initialize on. However, if it is needed in a lot of places and/or the impact of calling g_thread_init() is relatively minor anyway, there's a significant amount of setup code going on in that function. then perhaps a g_init() function is needed which we expect users to call first (like gtk_init()) GLib has so far supported the philosophy of not requirering an explicit initialization call. mostly due to requests by Owen and a few others. I would probably vote for initialising on demand. that'd have been ok for me as well, libgobject also requires that. but it's simply too late to demand that at this point, such source+ABI incompatible requirements can be introduced with 3.0 earliest. -- Regards, Martyn --- ciaoTJ ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Tim Janik wrote: Again, this feels more like an after thought and not really the ideal solution here. well, at this point there is no compelling reason for a gtk program to not enable threading i think. especially since recent file chooser backends have been reported to dmand-init threading anway (which is clearly *always* too late). so fallback initialization of threading in gtk_init() and friends sounds like a non-intrusive change that gets rid of the problem for a lot of affected non-gnome apps. do you have any concrete reason to object this? I do agree that there is no compelling reason for a gtk+ program to not enable threading though - that seems perfectly fine. However, I would rather only call g_thread_init() for special implementations and have glib initialise it for me if I don't call it first. This seems more logical to me and also means that it is up to us when we call g_thread_init(). I think the question that needs answering first is: What in glib requires g_thread_init() to be called first? With my relatively limited experience of glib, all I can think of is: - gasyncqueue - gmain - gthread - gthreadpool - gslice - gtimer off-head, there's are also threading initializers in glog and gmem.c. i don't think this is a question properly phrased/answered though. nothing in glib *needs* threading per se, except for dedicated threading APIs (e.g. conditions, or async pools). the question is whether all the threading aware code (which spreads throughout all of glib, to make it thread-safe in general) can cope with *late* g_thread_init() calls, and development has never focussed on that. (we intentionally avoided that by demanding early calls to g_thread_init if it is called at all.) And even now I think that is a good way of doing it. If we stick to this, I think having the g_thread_init() in gtk+ actually is a good idea. I think you either do that or have an initialisation function which allows the programmer to choose when calling _init() to enable threading or not (which should mean late thread initialisation would no longer be an issue). then perhaps a g_init() function is needed which we expect users to call first (like gtk_init()) GLib has so far supported the philosophy of not requirering an explicit initialization call. mostly due to requests by Owen and a few others. Is there any reason not to do this? I mean, I remember when I first started writing applications and it seems strange that glib didn't follow suite with gtk+, gnomevfs, etc. Also with talks of gnomevfs moving closer to glib, would you need an initialisation function ay some point anyway? The only other similar base library implementation I have used was in my last job and we did have an _init() function and you could specify a bunch of options, one of which was to enable threading (by default it was disabled). If this approach was taken, then gtk+ could still call g_init() with some variable to enable threading. I would probably vote for initialising on demand. that'd have been ok for me as well, libgobject also requires that. but it's simply too late to demand that at this point, such source+ABI incompatible requirements can be introduced with 3.0 earliest. Having a g_init() function is a much cleaner and more non-intrusive method of doing this. It makes more sense to me actually, I think you know (from a programmers point of view) if you are going to have threading enabled and that decision is best made as early as possible is it not? Would you ever want to call g_thread_init() late in a program's execution? -- Regards, Martyn ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
Hi, 2) Auto-initialize via g_thread_init (NULL) in gnome_init(). + this has already been done for newer GNOME libs, see: http://bugzilla.gnome.org/show_bug.cgi?id=343490 Unfortunately this doesn't work with the new GOption argument parsing, since you'll have to create the option context and its option group(s) before before calling gnome_program_init. (GOptionContext uses a GList for its list of groups, and GList uses GSlice.) Regards, Christian ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Tue, 2007-01-02 at 09:55 -0500, Martyn Russell wrote: With my relatively limited experience of glib, all I can think of is: - gasyncqueue - gmain - gthread - gthreadpool - gslice - gtimer If it is a small portion of the code (i.e. just the few modules listed (above) then perhaps it should be initialised on demand. However, if it is needed in a lot of places and/or the impact of calling g_thread_init() is relatively minor anyway, then perhaps a g_init() function is needed which we expect users to call first (like gtk_init()) On-demand initialization cannot be done without a performance penalty. It's not just about what glib does internally. App code depends on the fact that g_thread_init() is called before all other glib functions (and glib-using functions). For example, I use G_TRYLOCK() in Pango. That macro does nothing if threads are not initialized. Now if g_thread_init() is called after that G_TRYLOCK() and before the respective G_UNLOCK(), disaster happens. So, the only way to make it happen is to make G_TRYLOCK() initialize threads instead of doing nothing. That means, one would always pay the threads overhead AND that will not work, since gthreads is not linked necessarily. -- behdad http://behdad.org/ Those who would give up Essential Liberty to purchase a little Temporary Safety, deserve neither Liberty nor Safety. -- Benjamin Franklin, 1759 ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Ter, 2007-01-02 at 14:34 +0100, Tim Janik wrote: hey all. since the very early inception of the glib threading system, the docs say ( http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html ): You must call g_thread_init() before executing any other GLib functions in a threaded GLib program. In PyGObject it is virtually impossible to guarantee that g_thread_init() gets called before using some other GLib APIs. At least not without changing the API. That's because g_thread_init() is called by the python function gobject.threads_init(), but you obviously can't call gobject.threads_init() without importing gobject first, and of course import gobject already calls some GLib APIs... This is a very tricky problem :| -- Gustavo J. A. M. Carneiro [EMAIL PROTECTED] [EMAIL PROTECTED] The universe is always one step beyond logic ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Tue, 2 Jan 2007, Gustavo J. A. M. Carneiro wrote: On Ter, 2007-01-02 at 14:34 +0100, Tim Janik wrote: hey all. since the very early inception of the glib threading system, the docs say ( http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html ): You must call g_thread_init() before executing any other GLib functions in a threaded GLib program. In PyGObject it is virtually impossible to guarantee that g_thread_init() gets called before using some other GLib APIs. At least not without changing the API. That's because g_thread_init() is called by the python function gobject.threads_init(), but you obviously can't call gobject.threads_init() without importing gobject first, and of course import gobject already calls some GLib APIs... This is a very tricky problem :| what glib APIs are you calling there and why couldn't g_thread_init() be the first glib function to call there? -- Gustavo J. A. M. Carneiro [EMAIL PROTECTED] [EMAIL PROTECTED] The universe is always one step beyond logic --- ciaoTJ ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Jan 2, 2007, at 8:38 PM, Morten Welinder wrote: This leaves the question as to what macros it is safe to use before calling g_thread_init. I can look up the current definition of MIN and see, that yes it does not involve a function call, but that could change without notice in the next point release. Should it become a problem, nothing stops you from using your own definition of a macro. MIN is an easy case, because it is trivial. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: bugs regarding late g_thread_init() calls
On Wed, 2007-01-03 at 00:59 +0100, Tim Janik wrote: On Tue, 2 Jan 2007, Behdad Esfahbod wrote: On Tue, 2007-01-02 at 09:55 -0500, Martyn Russell wrote: With my relatively limited experience of glib, all I can think of is: - gasyncqueue - gmain - gthread - gthreadpool - gslice - gtimer If it is a small portion of the code (i.e. just the few modules listed (above) then perhaps it should be initialised on demand. However, if it is needed in a lot of places and/or the impact of calling g_thread_init() is relatively minor anyway, then perhaps a g_init() function is needed which we expect users to call first (like gtk_init()) On-demand initialization cannot be done without a performance penalty. It's not just about what glib does internally. App code depends on the fact that g_thread_init() is called before all other glib functions (and glib-using functions). For example, I use G_TRYLOCK() in Pango. That macro does nothing if threads are not initialized. Now if g_thread_init() is called after that G_TRYLOCK() and before the respective G_UNLOCK(), disaster happens. So, the only way to make it happen is to make G_TRYLOCK() initialize threads instead of doing nothing. That means, one would always pay the threads overhead AND that will not work, since gthreads is not linked necessarily. is that a general comment, or are you trying to argue against adding g_thread_init() to the start of gtk_init() (which is highly unlikely to be called between a trylock/unlock pair of pango ;) No. The point I was trying to make was that on-demand calling of g_thread_init doesn't work. Because one thread may call a function that triggers calling g_thread_init() and another thread may be inside a G_LOCK/G_UNLOCK pair, with the G_LOCK having been ignored because of no threads, and the G_UNLOCK call will be doomed. As for calling g_thread_init() in gtk_init(), this means gtk+ has to link to gthread, which it's not currently. Not that it's a problem. behdad http://behdad.org/ --- ciaoTJ -- behdad http://behdad.org/ Those who would give up Essential Liberty to purchase a little Temporary Safety, deserve neither Liberty nor Safety. -- Benjamin Franklin, 1759 ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list