libgsignon-glib first release 2.0.0
[profile/ivi/libgsignon-glib.git] / libgsignon-glib / sso-auth-service.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of libgsignon-glib
5  *
6  * Copyright (C) 2012 Canonical Ltd.
7  *
8  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * version 2.1 as published by the Free Software Foundation.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 #include <config.h>
26 #include "signon-errors.h"
27 #include "signon-internals.h"
28 #include "sso-auth-service.h"
29
30 static GHashTable *thread_objects = NULL;
31 static GMutex map_mutex;
32
33 static SsoAuthService *
34 get_singleton ()
35 {
36     SsoAuthService *object = NULL;
37
38     g_mutex_lock (&map_mutex);
39
40     if (thread_objects != NULL)
41     {
42         GWeakRef *ref;
43         ref = g_hash_table_lookup (thread_objects, g_thread_self ());
44         if (ref != NULL)
45         {
46             object = g_weak_ref_get (ref);
47         }
48     }
49
50     g_mutex_unlock (&map_mutex);
51     return object;
52 }
53
54 static void
55 g_thread_ref_free (GWeakRef *data)
56 {
57     g_slice_free (GWeakRef, data);
58 }
59
60 static void
61 set_singleton (SsoAuthService *object)
62 {
63     g_return_if_fail (IS_SSO_AUTH_SERVICE (object));
64
65     g_mutex_lock (&map_mutex);
66
67     if (thread_objects == NULL)
68     {
69         thread_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal,
70                 NULL, (GDestroyNotify)g_thread_ref_free);
71     }
72
73     if (object != NULL)
74     {
75         GWeakRef *ref = g_slice_new (GWeakRef);
76         g_weak_ref_init (ref, object);
77         g_hash_table_insert (thread_objects, g_thread_self (), ref);
78     }
79
80     g_mutex_unlock (&map_mutex);
81 }
82
83 static void
84 _on_auth_service_destroyed (gpointer data, GObject *obj)
85 {
86     (void)data;
87     (void)obj;
88     g_mutex_lock (&map_mutex);
89     if (thread_objects)
90     {
91         g_hash_table_unref (thread_objects);
92         thread_objects = NULL;
93     }
94     g_mutex_unlock (&map_mutex);
95 }
96
97
98 SsoAuthService *
99 sso_auth_service_get_instance ()
100 {
101     SsoAuthService *sso_auth_service = NULL;
102     GDBusConnection *connection = NULL;
103     GError *error = NULL;
104
105     sso_auth_service = get_singleton ();
106     if (sso_auth_service != NULL) return sso_auth_service;
107
108 #ifdef USE_P2P
109     gchar *bus_address = g_strdup_printf (SIGNOND_BUS_ADDRESS, g_get_user_runtime_dir());
110     connection = g_dbus_connection_new_for_address_sync (bus_address,
111                                                          G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
112                                                          NULL,
113                                                          NULL,
114                                                          &error);
115     g_free (bus_address);
116 #else
117     connection = g_bus_get_sync (SIGNOND_BUS_TYPE, NULL, &error);
118 #endif
119     /* Create the object */
120     sso_auth_service =
121         sso_auth_service_proxy_new_sync (connection,
122                                          G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
123 #ifdef USE_P2P
124                                          NULL,
125 #else
126                                          SIGNOND_SERVICE,
127 #endif
128                                          SIGNOND_DAEMON_OBJECTPATH,
129                                          NULL,
130                                          &error);
131     g_object_weak_ref (G_OBJECT (sso_auth_service), _on_auth_service_destroyed, sso_auth_service);
132     if (G_LIKELY (error == NULL)) {
133         set_singleton (sso_auth_service);
134     }
135     else
136     {
137         g_warning ("Couldn't activate signond: %s", error->message);
138         g_clear_error (&error);
139     }
140
141     /* While at it, register the error mapping with GDBus */
142     signon_error_quark ();
143
144     return sso_auth_service;
145 }