[Galago-commits] r2641 - in trunk/libgalago: . libgalago
galago-commits at freedesktop.org
galago-commits at freedesktop.org
Thu Mar 30 15:37:59 PST 2006
Author: chipx86
Date: 2006-03-30 15:37:50 -0800 (Thu, 30 Mar 2006)
New Revision: 2641
Modified:
trunk/libgalago/ChangeLog
trunk/libgalago/NEWS
trunk/libgalago/libgalago/galago-account.c
trunk/libgalago/libgalago/galago-context.c
trunk/libgalago/libgalago/galago-core.c
trunk/libgalago/libgalago/galago-person.c
trunk/libgalago/libgalago/galago-service.c
trunk/libgalago/libgalago/galago-service.h
trunk/libgalago/libgalago/galago-status.c
Log:
- Added better threading support. All global/static variables are now locked.
- Fixed a memory leak in GalagoPerson where session IDs weren't being freed.
- Changed galago_service_normalize() to return an allocated string instead of a static buffer. Also rewrote this to use GString and to hopefully be a little more efficient.
- Used GOnce where appropriate to initialize certain things only once.
Modified: trunk/libgalago/ChangeLog
===================================================================
--- trunk/libgalago/ChangeLog 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/ChangeLog 2006-03-30 23:37:50 UTC (rev 2641)
@@ -1,3 +1,22 @@
+Thu Mar 30 15:34:06 PST 2006 Christian Hammond <chipx86 at chipx86.com>
+
+ * libgalago/galago-account.c:
+ * libgalago/galago-context.c:
+ * libgalago/galago-core.c:
+ * libgalago/galago-person.c:
+ * libgalago/galago-service.c:
+ * libgalago/galago-service.h:
+ * libgalago/galago-status.c:
+ * NEWS:
+ - Added better threading support. All global/static variables are
+ now locked.
+ - Fixed a memory leak in GalagoPerson where session IDs weren't being
+ freed.
+ - Changed galago_service_normalize() to return an allocated string
+ instead of a static buffer. Also rewrote this to use GString and to
+ hopefully be a little more efficient.
+ - Used GOnce where appropriate to initialize certain things only once.
+
Wed Mar 29 22:15:25 PST 2006 Christian Hammond <chipx86 at chipx86.com>
* libgalago/galago-dbus.c:
Modified: trunk/libgalago/NEWS
===================================================================
--- trunk/libgalago/NEWS 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/NEWS 2006-03-30 23:37:50 UTC (rev 2641)
@@ -6,6 +6,7 @@
* "Added" signals are no longer blocked when retrieving a list of new
objects. Updated the docs to warn about potential problems in the users'
code that they should know about.
+ * Worked toward making libgalago more thread-safe.
GLib port:
- Replaced the home-brewn object model with GObject.
@@ -97,6 +98,9 @@
- galago_service_new() has been removed.
galago_create_service() should now be used.
- Clients can no longer create a foreign service.
+ - galago_service_normalize() now returns a pre-allocated string.
+ If you use this, make sure you're freeing the returned string
+ when no longer in use.
GalagoStatus:
- Added a GALAGO_STATUS_ATTR_MESSAGE define.
Modified: trunk/libgalago/libgalago/galago-account.c
===================================================================
--- trunk/libgalago/libgalago/galago-account.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-account.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -735,8 +735,8 @@
service = galago_account_get_service(account);
g_hash_table_insert(account->priv->contacts_table,
- g_strdup(galago_service_normalize(service, username)),
- contact);
+ galago_service_normalize(service, username),
+ contact);
account->priv->contacts = g_list_append(account->priv->contacts, contact);
@@ -778,6 +778,7 @@
{
GalagoAccount *contact;
GalagoService *service;
+ char *norm_username;
g_return_val_if_fail(account != NULL, NULL);
g_return_val_if_fail(GALAGO_IS_ACCOUNT(account), NULL);
@@ -785,9 +786,10 @@
service = galago_account_get_service(account);
- contact =
- g_hash_table_lookup(account->priv->contacts_table,
- galago_service_normalize(service, username));
+ norm_username = galago_service_normalize(service, username);
+ contact = g_hash_table_lookup(account->priv->contacts_table,
+ norm_username);
+ g_free(norm_username);
if (contact == NULL && query && GALAGO_OBJECT_IS_REMOTE(account) &&
!galago_is_daemon() && galago_is_connected())
Modified: trunk/libgalago/libgalago/galago-context.c
===================================================================
--- trunk/libgalago/libgalago/galago-context.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-context.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -71,9 +71,11 @@
**************************************************************************/
static void galago_context_destroy(GalagoObject *gobject);
-static GalagoObjectClass *parent_class = NULL;
+G_LOCK_DEFINE_STATIC(_contexts_lock);
static GList *contexts = NULL;
+static GalagoObjectClass *parent_class = NULL;
+
G_DEFINE_TYPE(GalagoContext, galago_context, GALAGO_TYPE_OBJECT);
static void
@@ -217,16 +219,24 @@
g_return_if_fail(context != NULL);
g_return_if_fail(GALAGO_IS_CONTEXT(context));
+ G_LOCK(_contexts_lock);
contexts = g_list_prepend(contexts, context);
+ G_UNLOCK(_contexts_lock);
}
void
galago_context_pop(void)
{
- GalagoContext *context = galago_context_get();
+ GalagoContext *context;
+ G_LOCK(_contexts_lock);
+
+ context = galago_context_get();
+
if (context != NULL)
contexts = g_list_remove(contexts, context);
+
+ G_UNLOCK(_contexts_lock);
}
GalagoContext *
Modified: trunk/libgalago/libgalago/galago-core.c
===================================================================
--- trunk/libgalago/libgalago/galago-core.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-core.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -102,8 +102,8 @@
static void _galago_dbus_core_add_person(GalagoPerson *person);
static void _galago_dbus_core_remove_person(GalagoPerson *person);
+G_LOCK_DEFINE_STATIC(_core_lock);
static GalagoCore *_core = NULL;
-static gboolean first_init = TRUE;
static GalagoContextOps context_ops =
{
@@ -234,9 +234,12 @@
static void
galago_core_init(GalagoCore *core)
{
+ G_LOCK(_core_lock);
+
_core = core;
+ galago_object_set_dbus_path(GALAGO_OBJECT(core), GALAGO_DBUS_CORE_OBJECT);
- galago_object_set_dbus_path(GALAGO_OBJECT(core), GALAGO_DBUS_CORE_OBJECT);
+ G_UNLOCK(_core_lock);
}
static void
@@ -265,7 +268,9 @@
if (_core->conn_obj_path != NULL)
g_free(_core->conn_obj_path);
+ G_LOCK(_core_lock);
_core = NULL;
+ G_UNLOCK(_core_lock);
G_OBJECT_CLASS(parent_class)->finalize(object);
}
@@ -828,10 +833,26 @@
}
#endif
+static gpointer
+register_exit_handlers(gpointer unused)
+{
+ g_atexit(_exit_galago);
+
+#ifdef HAVE_SIGNAL_H
+ if (signal(SIGINT, _sigint_cb) == SIG_ERR)
+ {
+ g_warning("Unable to register SIGINT signal handler");
+ }
+#endif /* HAVE_SIGNAL_H_ */
+
+ return NULL;
+}
+
gboolean
galago_init(const char *name, gboolean feed)
{
GalagoContext *context;
+ static GOnce first_init = G_ONCE_INIT;
g_return_val_if_fail(name != NULL, FALSE);
g_return_val_if_fail(*name != '\0', FALSE);
@@ -850,7 +871,9 @@
galago_context_push(context);
+ G_LOCK(_core_lock);
_core = g_object_new(GALAGO_TYPE_CORE, NULL);
+ G_UNLOCK(_core_lock);
_core->app_name = g_strdup(name);
_core->feed = feed;
@@ -861,20 +884,8 @@
if (!_galago_core_connect())
_galago_core_disconnect();
- if (first_init)
- {
- g_atexit(_exit_galago);
+ g_once(&first_init, register_exit_handlers, NULL);
-#ifdef HAVE_SIGNAL_H
- if (signal(SIGINT, _sigint_cb) == SIG_ERR)
- {
- g_warning("Unable to register SIGINT signal handler");
- }
-#endif /* HAVE_SIGNAL_H_ */
-
- first_init = TRUE;
- }
-
return TRUE;
}
Modified: trunk/libgalago/libgalago/galago-person.c
===================================================================
--- trunk/libgalago/libgalago/galago-person.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-person.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -32,6 +32,7 @@
{
char *id;
char *session_id;
+ char *display_name;
GalagoImage *photo;
GHashTable *accounts_table;
GList *accounts;
@@ -219,9 +220,9 @@
galago_context_remove_person(person);
galago_context_pop();
- if (person->priv->id != NULL)
- g_free(person->priv->id);
-
+ g_free(person->priv->id);
+ g_free(person->priv->session_id);
+ g_free(person->priv->display_name);
g_free(person->priv);
person->priv = NULL;
}
@@ -392,13 +393,16 @@
GalagoPerson *
galago_create_person(const char *uid)
{
+ G_LOCK_DEFINE_STATIC(session_id_lock);
static gulong next_session_id_index = 1;
char *session_id = NULL;
GalagoPerson *person;
g_return_val_if_fail(galago_is_initted(), NULL);
+ G_LOCK(session_id_lock);
session_id = g_strdup_printf("session-id-%ld", next_session_id_index++);
+ G_UNLOCK(session_id_lock);
person = _galago_person_new(uid, session_id, GALAGO_LOCAL, NULL);
@@ -480,7 +484,6 @@
const char *
galago_person_get_display_name(const GalagoPerson *person)
{
- static char buffer[BUFSIZ];
const char *first_name, *last_name;
g_return_val_if_fail(person != NULL, NULL);
@@ -488,6 +491,9 @@
/* XXX This is all a hack, but for now, it should work. Improve this! */
+ g_free(person->priv->display_name);
+ person->priv->display_name = NULL;
+
first_name = galago_object_get_attr_string(GALAGO_OBJECT(person),
GALAGO_PERSON_ATTR_FIRST_NAME);
last_name = galago_object_get_attr_string(GALAGO_OBJECT(person),
@@ -495,15 +501,13 @@
if (first_name != NULL || last_name != NULL)
{
- g_snprintf(buffer, sizeof(buffer), "%s%s%s",
- (first_name == NULL ? "" : first_name),
- (first_name != NULL && last_name != NULL ? " " : ""),
- (last_name == NULL ? "" : last_name));
-
- return buffer;
+ person->priv->display_name = g_strdup_printf("%s%s%s",
+ (first_name == NULL ? "" : first_name),
+ (first_name != NULL && last_name != NULL ? " " : ""),
+ (last_name == NULL ? "" : last_name));
}
- return NULL;
+ return person->priv->display_name;
}
void
@@ -671,7 +675,7 @@
}
key = g_new0(AccountCacheKey, 1);
- key->username = g_strdup(galago_service_normalize(service, username));
+ key->username = galago_service_normalize(service, username);
key->service = service;
g_hash_table_insert(person->priv->accounts_table, key, account);
@@ -696,7 +700,7 @@
service = galago_account_get_service(account);
username = galago_account_get_username(account);
- key.username = g_strdup(galago_service_normalize(service, username));
+ key.username = galago_service_normalize(service, username);
key.service = galago_account_get_service(account);
g_hash_table_remove(person->priv->accounts_table, &key);
@@ -726,7 +730,7 @@
galago_object_get_origin(GALAGO_OBJECT(service)),
NULL);
- key.username = g_strdup(galago_service_normalize(service, username));
+ key.username = galago_service_normalize(service, username);
key.service = service;
account = g_hash_table_lookup(person->priv->accounts_table, &key);
Modified: trunk/libgalago/libgalago/galago-service.c
===================================================================
--- trunk/libgalago/libgalago/galago-service.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-service.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -340,8 +340,8 @@
g_free(map_info);
}
-static void
-_init_service_id_map_table(void)
+static gpointer
+_init_service_id_map_table(gpointer unused)
{
ServiceMapInfo *map_info;
@@ -368,19 +368,21 @@
GALAGO_PRESERVE_SPACES);
ADD_SERVICE_MAP(GALAGO_SERVICE_ID_ZEPHYR, _("Zephyr"),
GALAGO_PRESERVE_SPACES | GALAGO_PRESERVE_CASE);
+
+ return NULL;
}
static ServiceMapInfo *
_galago_services_map_id_to_info(const char *id)
{
+ static GOnce map_init = G_ONCE_INIT;
ServiceMapInfo *map_info;
char *temp;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(*id != '\0', NULL);
- if (service_id_map_table == NULL)
- _init_service_id_map_table();
+ g_once(&map_init, _init_service_id_map_table, NULL);
temp = g_ascii_strdown(id, -1);
@@ -489,14 +491,16 @@
gboolean query)
{
GalagoAccount *account;
+ char *norm_username;
g_return_val_if_fail(service != NULL, NULL);
g_return_val_if_fail(username != NULL, NULL);
g_return_val_if_fail(GALAGO_IS_SERVICE(service), NULL);
- account = g_hash_table_lookup(
- service->priv->accounts_table,
- galago_service_normalize(service, username));
+ norm_username = galago_service_normalize(service, username);
+ account = g_hash_table_lookup(service->priv->accounts_table,
+ norm_username);
+ g_free(norm_username);
if (account == NULL && query && GALAGO_OBJECT_IS_REMOTE(service) &&
!galago_is_daemon() && galago_is_connected())
@@ -563,8 +567,7 @@
}
g_hash_table_insert(service->priv->accounts_table,
- g_strdup(galago_service_normalize(service, username)),
- account);
+ galago_service_normalize(service, username), account);
service->priv->accounts = g_list_append(service->priv->accounts, account);
@@ -578,6 +581,7 @@
_galago_service_remove_account(GalagoService *service, GalagoAccount *account)
{
const char *username;
+ char *norm_username;
g_return_if_fail(service != NULL);
g_return_if_fail(account != NULL);
@@ -585,10 +589,10 @@
g_return_if_fail(GALAGO_IS_ACCOUNT(account));
username = galago_account_get_username(account);
+ norm_username = galago_service_normalize(service, username);
+ g_hash_table_remove(service->priv->accounts_table, norm_username);
+ g_free(norm_username);
- g_hash_table_remove(service->priv->accounts_table,
- galago_service_normalize(service, username));
-
service->priv->accounts = g_list_remove(service->priv->accounts, account);
if (GALAGO_OBJECT_IS_LOCAL(service) && galago_is_connected() &&
@@ -602,12 +606,12 @@
g_signal_emit(service, signals[ACCOUNT_REMOVED], 0, account);
}
-const char *
+char *
galago_service_normalize(const GalagoService *service, const char *username)
{
- static char buffer[BUFSIZ];
+ GString *str;
+ char *buffer;
const char *c;
- char *d;
GalagoServiceFlags flags;
g_return_val_if_fail(service != NULL, NULL);
@@ -616,7 +620,11 @@
flags = galago_service_get_flags(service);
- for (c = username, d = buffer; *c != '\0'; c++)
+ str = g_string_new("");
+
+ for (c = username;
+ *c != '\0' && (!(flags & GALAGO_STRIP_SLASH) || *c != '/');
+ c++)
{
if (*c == ' ' && (flags & GALAGO_PRESERVE_SPACES) == 0)
{
@@ -624,23 +632,13 @@
c++;
}
- *d++ = *c;
+ g_string_append_c(str, *c);
}
- *d = '\0';
-
if ((flags & GALAGO_PRESERVE_CASE) == 0)
- {
- char *tmp = g_ascii_strdown(buffer, -1);
- strncpy(buffer, tmp, sizeof(buffer));
- g_free(tmp);
- }
+ g_string_ascii_down(str);
- if ((flags & GALAGO_STRIP_SLASH) == GALAGO_STRIP_SLASH &&
- (d = strchr(buffer, '/')) != NULL)
- {
- *d = '\0';
- }
+ buffer = g_string_free(str, FALSE);
return buffer;
}
Modified: trunk/libgalago/libgalago/galago-service.h
===================================================================
--- trunk/libgalago/libgalago/galago-service.h 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-service.h 2006-03-30 23:37:50 UTC (rev 2641)
@@ -222,16 +222,13 @@
* Normalizes an account username based on the service's normalization
* flags.
*
- * The returned string is stored internally in a status buffer. If you need
- * the string for long, make sure to g_strdup() it.
- *
* @param service The service.
* @param username The username to normalize.
*
- * @return The string, stored in a static buffer.
+ * @return The string. This must be freed.
*/
-const char *galago_service_normalize(const GalagoService *service,
- const char *username);
+char *galago_service_normalize(const GalagoService *service,
+ const char *username);
/*@}*/
Modified: trunk/libgalago/libgalago/galago-status.c
===================================================================
--- trunk/libgalago/libgalago/galago-status.c 2006-03-30 06:16:00 UTC (rev 2640)
+++ trunk/libgalago/libgalago/galago-status.c 2006-03-30 23:37:50 UTC (rev 2641)
@@ -442,8 +442,8 @@
#define ADD_STATUS_MAP(id, name) \
g_hash_table_insert(status_id_map_table, g_strdup(id), g_strdup(name));
-static void
-_init_status_id_map_table(void)
+static gpointer
+_init_status_id_map_table(gpointer unused)
{
status_id_map_table =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -456,16 +456,19 @@
ADD_STATUS_MAP(GALAGO_STATUS_ID_EXTENDED_AWAY, _("Extended Away"));
ADD_STATUS_MAP(GALAGO_STATUS_ID_HIDDEN, _("Hidden"));
ADD_STATUS_MAP(GALAGO_STATUS_ID_OFFLINE, _("Offline"));
+
+ return NULL;
}
static const char *
_galago_statuses_map_id_to_name(const char *id)
{
+ static GOnce map_init = G_ONCE_INIT;
+
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(*id != '\0', NULL);
- if (status_id_map_table == NULL)
- _init_status_id_map_table();
+ g_once(&map_init, _init_status_id_map_table, NULL);
return (const char *)g_hash_table_lookup(status_id_map_table, id);
}
More information about the galago-commits
mailing list