From 6ff36b489e55690230982c2151cee20b71508597 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 4 Feb 2010 23:19:19 -0500 Subject: [PATCH 16/22] Add session api for graceful shutdown This adds the StopResponse method and QueryStop, Stop and CancelStop signals. --- data/ConsoleKit.conf | 3 + src/ck-marshal.list | 1 + src/ck-session.c | 101 ++++++++++++++++++++++++++++ src/ck-session.h | 17 +++++ src/org.freedesktop.ConsoleKit.Session.xml | 80 ++++++++++++++++++++++ 5 files changed, 202 insertions(+), 0 deletions(-) diff --git a/data/ConsoleKit.conf b/data/ConsoleKit.conf index b5fc755..f46fb5c 100644 --- a/data/ConsoleKit.conf +++ b/data/ConsoleKit.conf @@ -154,6 +154,9 @@ send_member="GetIdleSinceHint"/> + diff --git a/src/ck-marshal.list b/src/ck-marshal.list index 7f60efc..9c1b690 100644 --- a/src/ck-marshal.list +++ b/src/ck-marshal.list @@ -1,3 +1,4 @@ VOID:UINT,STRING BOOLEAN:POINTER VOID:OBJECT,OBJECT +VOID:BOOLEAN,STRING diff --git a/src/ck-session.c b/src/ck-session.c index d434583..d5c3345 100644 --- a/src/ck-session.c +++ b/src/ck-session.c @@ -85,6 +85,10 @@ enum { UNLOCK, ACTIVE_CHANGED, IDLE_HINT_CHANGED, + STOP_RESPONSE, + QUERY_STOP, + STOP, + CANCEL_STOP, LAST_SIGNAL }; @@ -433,6 +437,14 @@ ck_session_get_id (CkSession *session, return TRUE; } +const char * +ck_session_peek_id (CkSession *session) +{ + g_return_val_if_fail (CK_IS_SESSION (session), NULL); + + return session->priv->id; +} + gboolean ck_session_get_seat_id (CkSession *session, char **id, @@ -971,6 +983,46 @@ ck_session_class_init (CkSessionClass *klass) g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + signals [STOP_RESPONSE] = + g_signal_new ("stop-response", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, stop_response), + NULL, + NULL, + ck_marshal_VOID__BOOLEAN_STRING, + G_TYPE_NONE, + 2, G_TYPE_BOOLEAN, G_TYPE_STRING); + signals [QUERY_STOP] = + g_signal_new ("query-stop", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, query_stop), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [STOP] = + g_signal_new ("stop", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, stop), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [CANCEL_STOP] = + g_signal_new ("cancel-stop", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, cancel_stop), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); g_object_class_install_property (object_class, PROP_ACTIVE, @@ -1359,3 +1411,52 @@ ck_session_dump (CkSession *session, g_free (group_name); } + +gboolean +ck_session_stop_response (CkSession *session, + gboolean ok, + const char *reason, + GError *error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_debug ("CkSession::stop-response %s ok=%d reason=%s", session->priv->id, ok, reason); + + g_signal_emit (session, signals[STOP_RESPONSE], 0, ok, reason); + + return TRUE; +} + +void +ck_session_query_stop (CkSession *session) +{ + g_return_if_fail (CK_IS_SESSION (session)); + + g_debug ("CkSession::query-stop %s", session->priv->id); + + /* TODO unicast the signal only to the session */ + g_signal_emit (session, signals[QUERY_STOP], 0); +} + +void +ck_session_stop (CkSession *session) +{ + g_return_if_fail (CK_IS_SESSION (session)); + + g_debug ("CkSession::stop %s", session->priv->id); + + /* TODO unicast the signal only to the session */ + g_signal_emit (session, signals[STOP], 0); +} + +void +ck_session_cancel_stop (CkSession *session) +{ + g_return_if_fail (CK_IS_SESSION (session)); + + g_debug ("CkSession::cancel-stop %s", session->priv->id); + + /* TODO unicast the signal only to the session */ + g_signal_emit (session, signals[CANCEL_STOP], 0); +} + diff --git a/src/ck-session.h b/src/ck-session.h index b6b565b..66c43d0 100644 --- a/src/ck-session.h +++ b/src/ck-session.h @@ -49,6 +49,9 @@ typedef struct /* internal signals */ void (* activate) (CkSession *session, DBusGMethodInvocation *context); + void (* stop_response) (CkSession *session, + gboolean ok, + const char *reason); /* exported signals */ void (* lock) (CkSession *session); @@ -57,6 +60,10 @@ typedef struct gboolean active); void (* idle_hint_changed) (CkSession *session, gboolean idle_hint); + void (* query_stop) (CkSession *session); + void (* stop) (CkSession *session); + void (* cancel_stop) (CkSession *session); + } CkSessionClass; typedef enum @@ -74,6 +81,7 @@ CkSession * ck_session_new_with_parameters (const char *ss const char *cookie, const GPtrArray *parameters); +const char * ck_session_peek_id (CkSession *session); void ck_session_dump (CkSession *session, GKeyFile *key_file); void ck_session_run_programs (CkSession *session, @@ -156,6 +164,10 @@ gboolean ck_session_get_remote_host_name (CkSession *se gboolean ck_session_get_creation_time (CkSession *session, char **iso8601_datetime, GError **error); +void ck_session_query_stop (CkSession *session); +void ck_session_stop (CkSession *session); +void ck_session_cancel_stop (CkSession *session); + /*deprecated*/ gboolean ck_session_get_user (CkSession *session, guint *uid, @@ -172,6 +184,11 @@ gboolean ck_session_set_idle_hint (CkSession *se gboolean idle_hint, DBusGMethodInvocation *context); +gboolean ck_session_stop_response (CkSession *session, + gboolean ok, + const char *reason, + GError *error); + /* Privileged actions */ gboolean ck_session_activate (CkSession *session, DBusGMethodInvocation *context); diff --git a/src/org.freedesktop.ConsoleKit.Session.xml b/src/org.freedesktop.ConsoleKit.Session.xml index b6e1cdb..95221f7 100644 --- a/src/org.freedesktop.ConsoleKit.Session.xml +++ b/src/org.freedesktop.ConsoleKit.Session.xml @@ -276,6 +276,86 @@ + + + + Whether or not it is OK to proceed + + + + + The reason string + + + + + + This method should be called by a session leader in response to + the QueryStop + and Stop + signals. + + + + + + + + + + This signal is used to inform the session that the system is + about to be stopped. The session leader should pass this + information on to its clients (e.g using the + org.gnome.SessionManager.QueryEndSession signal), and respond + back by calling StopResponse() + on the session object corresponding to its session within two + seconds of the signal emission. + + + No actions or user interaction are allowed in response to this + signal. Any actions required for a clean shutdown should take + place in response to the Stop signal. + + + Sessions should limit operations after this signal until either + a Stop or a + CancelStop signal + is received. + + + + + + + + + + This signal is used to inform the session that the system is + about to be stopped. The session leader should pass this + information on to its clients (e.g using the + org.gnome.SessionManager.EndSession signal), and respond + back by calling StopResponse() on the session + object corresponding to its session within 11 seconds of + the signal emission. + + + + + + + + + + This signal indicates that a previous emission of QueryStop has been + cancelled. Sessions should resume normal operation. + + + + + -- 1.6.6