-->

GLib: Graceful termination of GApplication on Unix

2019-05-19 10:03发布

问题:

When the user hits Ctrl+C in a Posix / Linux shell with a program running, that program recieves a SIGINT signal. When running a program based on GApplication, this means that the program gets terminated immediately.

How can I overcome this and have GApplication shut down gracefully?

回答1:

You can use g_unix_signal_add(). This function takes a callback that is called once the program recieves the signal you specify. (SIGINT in this case)

That callback should then call g_application_release() until the GApplication's use count dropped to zero. Once that is the case, the Main Loop will terminate and GApplication's shutdown signal will be emitted. By handling that signal you can do all necessary deinitialization tasks before the program will terminate.

(taken from the reference manual:)

GApplication provides convenient life cycle management by maintaining a "use count" for the primary application instance. The use count can be changed using g_application_hold() and g_application_release(). If it drops to zero, the application exits. Higher-level classes such as GtkApplication employ the use count to ensure that the application stays alive as long as it has any opened windows.

An example in Vala:

public class MyApplication : Application {
    public MyApplication () {
        Object (flags: ApplicationFlags.FLAGS_NONE);

        startup.connect (on_startup);
        activate.connect (on_activate);
        shutdown.connect (on_shutdown);

        Unix.signal_add (
            Posix.SIGINT,
            on_sigint,
            Priority.DEFAULT
        );
    }

    private bool on_sigint () {
        release ();
        return Source.REMOVE;
    }

    private void on_startup () {
        print ("Startup\n");
    }

    private void on_activate () {
        print ("command line\n");
        hold ();
    }

    private void on_shutdown () {
        print ("Shutdown\n");
    }
}

void main (string[] args) {
    new MyApplication ().run ();
}

(compile with valac foo.vala --pkg gio-2.0 --pkg posix)