summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-10-10 12:53:45 -0400
committerWilliam Jon McCann <mccann@jhu.edu>2007-10-10 12:53:45 -0400
commitbd43c78b3ab2ec7f85b17cca46d4b46f8671cd29 (patch)
tree0560ef7122b69f9f64f1eff054d620ab1398ad6e
parenta90ecd3544f03c16f6c5a97aafb1c0b33b58101c (diff)
remove session/seat from list before signaling
We should remove the session or seat from the lists before calling out or emitting a signal. We steal from the lists and then unref the objects when the signal is complete.
-rw-r--r--src/ck-manager.c57
-rw-r--r--src/ck-seat.c28
2 files changed, 66 insertions, 19 deletions
diff --git a/src/ck-manager.c b/src/ck-manager.c
index 377cef0..c957896 100644
--- a/src/ck-manager.c
+++ b/src/ck-manager.c
@@ -307,19 +307,43 @@ static void
remove_seat (CkManager *manager,
CkSeat *seat)
{
- char *sid;
+ char *sid;
+ char *orig_sid;
+ CkSeat *orig_seat;
+ gboolean res;
sid = NULL;
ck_seat_get_id (seat, &sid, NULL);
+ /* Need to get the original key/value */
+ res = g_hash_table_lookup_extended (manager->priv->seats,
+ sid,
+ (gpointer *)&orig_sid,
+ (gpointer *)&orig_seat);
+ if (! res) {
+ g_debug ("Seat %s is not attached", sid);
+ goto out;
+ }
+
+ /* Remove the seat from the list but don't call
+ * unref until the signal is emitted */
+ g_hash_table_steal (manager->priv->seats, sid);
+
if (sid != NULL) {
g_hash_table_remove (manager->priv->seats, sid);
}
+ g_debug ("Emitting seat-removed: %s", sid);
g_signal_emit (manager, signals [SEAT_REMOVED], 0, sid);
g_debug ("Removed seat: %s", sid);
+ if (orig_seat != NULL) {
+ g_object_unref (orig_seat);
+ }
+ g_free (orig_sid);
+
+ out:
g_free (sid);
}
@@ -1175,10 +1199,11 @@ remove_session_for_cookie (CkManager *manager,
const char *cookie,
GError **error)
{
- CkSession *session;
+ CkSession *orig_session;
+ char *orig_ssid;
LeaderInfo *leader_info;
- char *ssid;
char *sid;
+ gboolean res;
g_debug ("Removing session for cookie: %s", cookie);
@@ -1192,8 +1217,12 @@ remove_session_for_cookie (CkManager *manager,
return FALSE;
}
- session = g_hash_table_lookup (manager->priv->sessions, leader_info->ssid);
- if (session == NULL) {
+ /* Need to get the original key/value */
+ res = g_hash_table_lookup_extended (manager->priv->sessions,
+ leader_info->ssid,
+ (gpointer *)&orig_ssid,
+ (gpointer *)&orig_session);
+ if (! res) {
g_set_error (error,
CK_MANAGER_ERROR,
CK_MANAGER_ERROR_GENERAL,
@@ -1201,17 +1230,20 @@ remove_session_for_cookie (CkManager *manager,
return FALSE;
}
- ssid = g_strdup (leader_info->ssid);
+ /* Remove the session from the list but don't call
+ * unref until the removed from seats */
+ g_hash_table_steal (manager->priv->sessions, leader_info->ssid);
/* remove from seat */
- ck_session_get_seat_id (session, &sid, NULL);
+ sid = NULL;
+ ck_session_get_seat_id (orig_session, &sid, NULL);
if (sid != NULL) {
CkSeat *seat;
seat = g_hash_table_lookup (manager->priv->seats, sid);
if (seat != NULL) {
CkSeatKind kind;
- ck_seat_remove_session (seat, session, NULL);
+ ck_seat_remove_session (seat, orig_session, NULL);
kind = CK_SEAT_KIND_STATIC;
/* if dynamic seat has no sessions then remove it */
@@ -1221,11 +1253,12 @@ remove_session_for_cookie (CkManager *manager,
}
}
}
-
- g_hash_table_remove (manager->priv->sessions, ssid);
-
g_free (sid);
- g_free (ssid);
+
+ if (orig_session != NULL) {
+ g_object_unref (orig_session);
+ }
+ g_free (orig_ssid);
manager_update_system_idle_hint (manager);
diff --git a/src/ck-seat.c b/src/ck-seat.c
index 63d7b6c..66bf728 100644
--- a/src/ck-seat.c
+++ b/src/ck-seat.c
@@ -528,8 +528,11 @@ ck_seat_remove_session (CkSeat *seat,
CkSession *session,
GError **error)
{
- char *ssid;
- gboolean ret;
+ char *ssid;
+ char *orig_ssid;
+ CkSession *orig_session;
+ gboolean res;
+ gboolean ret;
g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
@@ -537,7 +540,12 @@ ck_seat_remove_session (CkSeat *seat,
ssid = NULL;
ck_session_get_id (session, &ssid, NULL);
- if (g_hash_table_lookup (seat->priv->sessions, ssid) == NULL) {
+ /* Need to get the original key/value */
+ res = g_hash_table_lookup_extended (seat->priv->sessions,
+ ssid,
+ (gpointer *)&orig_ssid,
+ (gpointer *)&orig_session);
+ if (! res) {
g_debug ("Session %s is not attached to seat %s", ssid, seat->priv->id);
g_set_error (error,
CK_SEAT_ERROR,
@@ -548,17 +556,23 @@ ck_seat_remove_session (CkSeat *seat,
g_signal_handlers_disconnect_by_func (session, session_activate, seat);
- ck_session_run_programs (session, "session_removed");
+ /* Remove the session from the list but don't call
+ * unref until the signal is emitted */
+ g_hash_table_steal (seat->priv->sessions, ssid);
- g_debug ("Emitting removed signal: %s", ssid);
+ ck_session_run_programs (session, "session_removed");
+ g_debug ("Emitting session-removed: %s", ssid);
g_signal_emit (seat, signals [SESSION_REMOVED], 0, ssid);
- g_hash_table_remove (seat->priv->sessions, ssid);
-
/* try to change the active session */
maybe_update_active_session (seat);
+ if (orig_session != NULL) {
+ g_object_unref (orig_session);
+ }
+ g_free (orig_ssid);
+
ret = TRUE;
out:
g_free (ssid);