diff --git a/obexd/src/main.c b/obexd/src/main.c
index 8fc5618..91ed2cd 100644
--- a/obexd/src/main.c
+++ b/obexd/src/main.c
if (driver == NULL)
return;
- context = g_try_new0(struct phonebook_context, 1);
+ context = phonebook_create(driver);
if (context == NULL)
return;
- driver->create(context);
+ phonebook_pullphonebook(context);
- driver->destroy(context);
-
- g_free(context);
+ phonebook_unref(context);
}
static void tty_init(int service, const gchar *root_path, const gchar *capability,
diff --git a/obexd/src/phonebook.c b/obexd/src/phonebook.c
index e4203bc..7600be9 100644
--- a/obexd/src/phonebook.c
+++ b/obexd/src/phonebook.c
driver_list = g_slist_remove(driver_list, driver);
}
+struct phonebook_context *phonebook_create(struct phonebook_driver *driver)
+{
+ struct phonebook_context *context;
+
+ if (driver == NULL)
+ return NULL;
+
+ context = g_try_new0(struct phonebook_context, 1);
+ if (context == NULL)
+ return NULL;
+
+ DBG("context %p", context);
+
+ context->refcount = 1;
+ context->driver = driver;
+
+ if (driver->create) {
+ if (driver->create(context) < 0) {
+ g_free(context);
+ return NULL;
+ }
+ }
+
+ return context;
+}
+
+struct phonebook_context *phonebook_ref(struct phonebook_context *context)
+{
+ DBG("context %p refcount %d", context,
+ g_atomic_int_get(&context->refcount) + 1);
+
+ g_atomic_int_inc(&context->refcount);
+
+ return context;
+}
+
+void phonebook_unref(struct phonebook_context *context)
+{
+ DBG("context %p refcount %d", context,
+ g_atomic_int_get(&context->refcount) - 1);
+
+ if (g_atomic_int_dec_and_test(&context->refcount) == TRUE) {
+ if (context->driver->destroy)
+ context->driver->destroy(context);
+ g_free(context);
+ }
+}
+
+void phonebook_pullphonebook(struct phonebook_context *context)
+{
+ DBG("context %p", context);
+
+ if (context->driver->pullphonebook) {
+ phonebook_ref(context);
+
+ context->driver->pullphonebook(context);
+ }
+}
+
void phonebook_return(struct phonebook_context *context,
unsigned char *buf, int size)
{
DBG("context %p", context);
+
+ phonebook_unref(context);
}
struct phonebook_driver *phonebook_get_driver(const char *name)
diff --git a/obexd/src/phonebook.h b/obexd/src/phonebook.h
index 57e79b7..4eb7a2c 100644
--- a/obexd/src/phonebook.h
+++ b/obexd/src/phonebook.h
*
*/
+#include <glib.h>
+
+struct phonebook_driver;
+
struct phonebook_context {
+ gint refcount;
+
+ struct phonebook_driver *driver;
void *driver_data;
};
-struct phonebook_driver {
- const char *name;
- int (*create) (struct phonebook_context *context);
- void (*destroy) (struct phonebook_context *context);
- int (*pullphonebook) (struct phonebook_context *context, ...);
- int (*pullvcardlisting) (struct phonebook_context *context, ...);
- int (*pullvcardentry) (struct phonebook_context *context, ...);
-};
+extern struct phonebook_context *phonebook_create(struct phonebook_driver *driver);
+extern struct phonebook_context *phonebook_ref(struct phonebook_context *context);
+extern void phonebook_unref(struct phonebook_context *context);
static inline void *phonebook_get_data(struct phonebook_context *context)
{
context->driver_data = data;
}
-extern int phonebook_driver_register(struct phonebook_driver *driver);
-extern void phonebook_driver_unregister(struct phonebook_driver *driver);
-
+extern void phonebook_pullphonebook(struct phonebook_context *context);
extern void phonebook_return(struct phonebook_context *context,
unsigned char *buf, int size);
+struct phonebook_driver {
+ const char *name;
+ int (*create) (struct phonebook_context *context);
+ void (*destroy) (struct phonebook_context *context);
+ int (*pullphonebook) (struct phonebook_context *context);
+ int (*pullvcardlisting) (struct phonebook_context *context);
+ int (*pullvcardentry) (struct phonebook_context *context);
+};
+
+extern int phonebook_driver_register(struct phonebook_driver *driver);
+extern void phonebook_driver_unregister(struct phonebook_driver *driver);
+
struct phonebook_driver *phonebook_get_driver(const char *name);