core: allow multiple authority changed callbacks

We'll need this later; just keep all registered callbacks
in a list and track them by func/data.
This commit is contained in:
Dan Williams 2011-07-01 14:16:52 -05:00
parent db6638623b
commit 937970f60c
3 changed files with 68 additions and 29 deletions

View file

@ -545,45 +545,82 @@ typedef struct {
gpointer changed_data;
} PkChangedInfo;
static GSList *funcs = NULL;
#if WITH_POLKIT
static void
pk_authority_changed_cb (GObject *object, PkChangedInfo *info)
pk_authority_changed_cb (GObject *object, gpointer unused)
{
info->changed_callback (info->changed_data);
GSList *iter;
for (iter = funcs; iter; iter = g_slist_next (iter)) {
PkChangedInfo *info = iter->data;
info->changed_callback (info->changed_data);
}
}
#endif
void
nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data)
nm_auth_changed_func_register (GDestroyNotify callback, gpointer callback_data)
{
#if WITH_POLKIT
static PkChangedInfo info = { NULL, NULL };
static guint32 changed_id = 0;
PolkitAuthority *authority;
static guint32 changed_id = 0;
#endif
PkChangedInfo *info;
GSList *iter;
gboolean found = FALSE;
#if WITH_POLKIT
authority = pk_authority_get ();
if (!authority)
return;
if (callback == NULL) {
/* Clearing the callback */
info.changed_callback = NULL;
info.changed_data = NULL;
g_signal_handler_disconnect (authority, changed_id);
changed_id = 0;
} else {
info.changed_callback = callback;
info.changed_data= callback_data;
/* Hook up the changed signal the first time a callback is registered */
if (changed_id == 0) {
changed_id = g_signal_connect (authority,
"changed",
G_CALLBACK (pk_authority_changed_cb),
&funcs);
}
#endif
if (changed_id == 0) {
changed_id = g_signal_connect (authority,
"changed",
G_CALLBACK (pk_authority_changed_cb),
&info);
/* No duplicates */
for (iter = funcs; iter; iter = g_slist_next (iter)) {
info = iter->data;
if ((callback == info->changed_callback) && (callback_data == info->changed_data)) {
found = TRUE;
break;
}
}
g_warn_if_fail (found == FALSE);
if (found == FALSE) {
info = g_malloc0 (sizeof (*info));
info->changed_callback = callback;
info->changed_data = callback_data;
funcs = g_slist_append (funcs, info);
}
#if WITH_POLKIT
g_object_unref (authority);
#endif
}
void
nm_auth_changed_func_unregister (GDestroyNotify callback, gpointer callback_data)
{
GSList *iter;
for (iter = funcs; iter; iter = g_slist_next (iter)) {
PkChangedInfo *info = iter->data;
if ((callback == info->changed_callback) && (callback_data == info->changed_data)) {
g_free (info);
funcs = g_slist_delete_link (funcs, iter);
break;
}
}
}

View file

@ -102,7 +102,9 @@ gboolean nm_auth_uid_in_acl (NMConnection *connection,
gulong uid,
char **out_error_desc);
void nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data);
void nm_auth_changed_func_register (GDestroyNotify callback, gpointer callback_data);
void nm_auth_changed_func_unregister (GDestroyNotify callback, gpointer callback_data);
#endif /* NM_MANAGER_AUTH_H */

View file

@ -3083,6 +3083,13 @@ nm_manager_get (NMSettings *settings,
return singleton;
}
static void
authority_changed_cb (gpointer user_data)
{
/* Let clients know they should re-check their authorization */
g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
}
static void
dispose (GObject *object)
{
@ -3100,7 +3107,7 @@ dispose (GObject *object)
g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL);
g_slist_free (priv->auth_chains);
nm_auth_set_changed_func (NULL, NULL);
nm_auth_changed_func_unregister (authority_changed_cb, manager);
while (g_slist_length (priv->devices)) {
priv->devices = remove_one_device (manager,
@ -3376,13 +3383,6 @@ periodic_update_active_connection_timestamps (gpointer user_data)
return TRUE;
}
static void
authority_changed_cb (gpointer user_data)
{
/* Let clients know they should re-check their authorization */
g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
}
static void
nm_manager_init (NMManager *manager)
{
@ -3481,7 +3481,7 @@ nm_manager_init (NMManager *manager)
nm_log_warn (LOGD_SUSPEND, "could not initialize UPower D-Bus proxy");
/* Listen for authorization changes */
nm_auth_set_changed_func (authority_changed_cb, manager);
nm_auth_changed_func_register (authority_changed_cb, manager);
/* Monitor the firmware directory */
if (strlen (KERNEL_FIRMWARE_DIR)) {