Diff between c79d67ac1f7d91759a77f7a7397701d178e0b4a9 and e3f45996df7eb23484f62b8f0ae114b8a1f5952a

Changed Files

File Additions Deletions Status
obexd/src/main.c +3 -5 modified
obexd/src/phonebook.c +61 -0 modified
obexd/src/phonebook.h +23 -11 modified

Full Patch

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
@@ -68,15 +68,13 @@ static void test_phonebook(void)
 	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
@@ -48,10 +48,71 @@ void phonebook_driver_unregister(struct phonebook_driver *driver)
 	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
@@ -21,18 +21,20 @@
  *
  */
 
+#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)
 {
@@ -45,10 +47,20 @@ static inline void phonebook_set_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);