[Gtk-sharp-list] Example code: Thread.Init() breaks single core machine

Aaron Oxford aaron at hardwarehookups.com.au
Tue Apr 10 11:16:35 EDT 2007


Hey everyone.

Can I please get some feedback on whether the following code locks up 
on your non-AMDX2 Windows machines? The code simulates a situation 
where the first thing you want to do is show a dialog over the main 
window, e.g. because some config file failed to load. The code works 
great on my AMD X2 natively. Under VMWare (which IME behaves like 
single core or Intel dual core system) the code breaks. And guess 
what... if I remove the Thread.Init() magic the situation reverses. Hooray! :-D

using System;
using Gtk;
using Gdk;

public class Test
{
     private Label label = null;
     private int counter = 0;
     private bool configurationFailed = false;
     private Gtk.Window wnd;

     // Want to display a dialog, but can't.
     public static void Main()
     {
         if (!GLib.Thread.Supported) GLib.Thread.Init();
         Gdk.Threads.Init();
         Application.Init();

         Test t = new Test();

         // After constructing main window.
         t.showMessage("ioLet Composer.");

         // Start the timer.
         GLib.Timeout.Add(100, new GLib.TimeoutHandler(t.Tick));

         // After starting the timer.
         //t.showMessage("VioLet Composer.");

         Gdk.Threads.Enter();

         // After the magic call.
         //t.showMessage("oLet Composer.");

         Application.Run();
         Gdk.Threads.Leave();
     }

     public Test()
     {
         wnd = new Gtk.Window("Test");
         wnd.Destroyed += new EventHandler(wnd_Destroyed);

         // Ladida, Gtk# is cool...
         VBox vbox = new VBox();
         label = new Label(counter.ToString());
         vbox.PackStart(label, false, false, 0);
         wnd.Add(vbox);
         wnd.ShowAll();

         // and then for some reason...
         configurationFailed = true;
     }

     void wnd_Destroyed(object sender, EventArgs e)
     {
         Application.Quit();
     }

     private bool Tick()
     {
         if (configurationFailed)
         {
             // During a timer
             //showMessage("new settings for VioLet Composer.");
             configurationFailed = false;
         }
         label.Text = "" + counter;
         counter++;
         return true;
     }

     private void showMessage(string p)
     {
         Gtk.Dialog dlg = new Dialog("caption", wnd, DialogFlags.Modal);
         dlg.AddButton(Gtk.Stock.Ok, Gtk.ResponseType.Ok);
         dlg.DefaultResponse = Gtk.ResponseType.Ok;
         ScrolledWindow sw = new ScrolledWindow();
         Label l = new Label(p);
         l.Wrap = true;
         sw.AddWithViewport(l);
         dlg.VBox.PackStart(sw);
         dlg.SetDefaultSize(320, 160);

         dlg.ShowAll();
         dlg.Run();
         dlg.Destroy();
     }
}

Because of the whole Application.Run() thing, there's no way to hook 
when your main window *actually* opens, only when it's shown. I spent 
a lot of time tonight thinking my problem was just that I was 
Run()ning the modal dialog before the Application was Run(). 
Apparently that isn't a problem.

But then, you'd expect timer callbacks don't start until things are 
Run(), right...? Wrong! I've just wasted the second half of the 
evening trying to work out the order of operations of Gtk# startup 
only to discover Gtk# itself really doesn't seem to care, except 
where this threading stuff is concerned. After finding out that I 
could start a timer and then not Run() the Application before the 
first timeout, I realised it was just another one of those things 
that someone writing single threaded C++ doesn't think about.

So how does one safely open a dialog (ok, maybe just without crashing 
to start with) as a result of something that happened before the main 
window was opened? I can't possibly be the first person in the world 
to be doing this, so I'm going to start by assuming I've done 
something wrong again, but I will be looking at Gtk# with much more 
closely this time. ;-)

[Sigh] So this is why Linux users are always talking about porting - 
they have so much time in between actually being able to do it. :-D

Aaron.
---------------------------------------------------------------------------------
Aaron Oxford   -   aaron+hardwarehookups .com .au
Director, Innovative Computer Solutions (Aust) Pty. Ltd.
49 Maitland Rd, Mayfield, NSW 2304 Australia
http://www.ic-solutions.com.au
Developer, SourceForge project VioLet Composer
http://sourceforge.net/projects/buzz-like



More information about the Gtk-sharp-list mailing list