I have been whining about features that I want in Vala to Jürg. To make up for all the time he lost listening to me I decided to fix two Vala bugs.
The first bug I fixed was using a recursive mutex for lock statements. Code like this will work as expected now:
public class LockMe : GLib.Object { } public class Executer : GLib.Object { LockMe o { get; set; } construct { o = new LockMe (); } void Internal () { lock (o) { } } public void Method () { lock (o) { Internal (); } } } public class App : GLib.Object { static void main (string[] args) { Executer e = new Executer (); e.Method (); } }
Here’s a gdb session that most GLib programmers will recognize:
Breakpoint 1, 0x08048a87 in executer_Method () (gdb) break g_static_rec_mutex_lock Breakpoint 2 at 0xb7e4d0e6 (gdb) cont Continuing. Breakpoint 2, 0xb7e4d0e6 in g_static_rec_mutex_lock () from /usr/lib/libglib-2.0.so.0 (gdb) bt #0 0xb7e4d0e6 in g_static_rec_mutex_lock () from /usr/lib/libglib-2.0.so.0 #1 0x08048b04 in executer_Method () #2 0x08049046 in app_main () #3 0x0804908a in main () (gdb) cont Continuing. Breakpoint 2, 0xb7e4d0e6 in g_static_rec_mutex_lock () from /usr/lib/libglib-2.0.so.0 (gdb) bt #0 0xb7e4d0e6 in g_static_rec_mutex_lock () from /usr/lib/libglib-2.0.so.0 #1 0x08048a6e in executer_Internal () #2 0x08048b0f in executer_Method () #3 0x08049046 in app_main () #4 0x0804908a in main () (gdb) cont Continuing. Program exited normally. (gdb)
The second bug is supporting interfaces for D-Bus services in Vala. It goes like this:
using GLib; [DBus (name = "org.gnome.TestServer")] public interface TestServerAPI { public abstract int64 ping (string msg); } public class TestServer : Object, TestServerAPI { int64 counter; public int64 ping (string msg) { message (msg); return counter++; } } void main () { MainLoop loop = new MainLoop (null, false); try { var conn = DBus.Bus.get (DBus.BusType.SESSION); dynamic DBus.Object bus = conn.get_object ( "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus"); uint request_name_result = bus.RequestName ("org.gnome.TestService", 0); if (request_name_result == DBus.RequestNameReply.PRIMARY_OWNER) { // start server var server = new TestServer (); conn.register_object ("/org/gnome/test", server); loop.run (); } else { // client dynamic DBus.Object test_server_object = conn.get_object ("org.gnome.TestService", "/org/gnome/test", "org.gnome.TestServer"); int64 pong = test_server_object.ping ("Hello from Vala"); message (pong.to_string ()); } } catch (Error foo) { } }