Diff between 1dc2ad6f0b7016fe8b61ef7c7314030823534139 and 31ebc74e69a833122cdc1c25078e614c7d7895bb

Changed Files

File Additions Deletions Status
gobex/gobex.c +16 -1 modified
gobex/gobex.h +4 -0 modified
unit/test-gobex.c +36 -0 modified

Full Patch

diff --git a/gobex/gobex.c b/gobex/gobex.c
index 7c6e586..be65fea 100644
--- a/gobex/gobex.c
+++ b/gobex/gobex.c
@@ -54,6 +54,9 @@ struct _GObex {
 	GObexRequestFunc req_func;
 	gpointer req_func_data;
 
+	GObexDisconnectFunc disconn_func;
+	gpointer disconn_func_data;
+
 	struct pending_pkt *pending_req;
 };
 
@@ -247,6 +250,13 @@ void g_obex_set_request_function(GObex *obex, GObexRequestFunc func,
 	obex->req_func_data = user_data;
 }
 
+void g_obex_set_disconnect_function(GObex *obex, GObexDisconnectFunc func,
+							gpointer user_data)
+{
+	obex->disconn_func = func;
+	obex->disconn_func_data = user_data;
+}
+
 static void parse_connect_data(GObex *obex, GObexPacket *pkt)
 {
 	const struct connect_data *data;
@@ -393,6 +403,10 @@ failed:
 	g_io_channel_unref(obex->io);
 	obex->io = NULL;
 	obex->io_source = 0;
+
+	if (obex->disconn_func)
+		obex->disconn_func(obex, obex->disconn_func_data);
+
 	return FALSE;
 }
 
@@ -455,7 +469,8 @@ void g_obex_unref(GObex *obex)
 	g_queue_foreach(obex->tx_queue, (GFunc) pending_pkt_free, NULL);
 	g_queue_free(obex->tx_queue);
 
-	g_io_channel_unref(obex->io);
+	if (obex->io != NULL)
+		g_io_channel_unref(obex->io);
 
 	if (obex->io_source > 0)
 		g_source_remove(obex->io_source);
diff --git a/gobex/gobex.h b/gobex/gobex.h
index 5823eac..01a871c 100644
--- a/gobex/gobex.h
+++ b/gobex/gobex.h
@@ -37,6 +37,7 @@ typedef void (*GObexRequestFunc) (GObex *obex, GObexPacket *req,
 							gpointer user_data);
 typedef void (*GObexResponseFunc) (GObex *obex, GError *err, GObexPacket *rsp,
 							gpointer user_data);
+typedef void (*GObexDisconnectFunc) (GObex *obex, gpointer user_data);
 
 gboolean g_obex_send(GObex *obex, GObexPacket *pkt);
 
@@ -47,6 +48,9 @@ gboolean g_obex_cancel_req(GObex *obex, guint req_id);
 void g_obex_set_request_function(GObex *obex, GObexRequestFunc func,
 							gpointer user_data);
 
+void g_obex_set_disconnect_function(GObex *obex, GObexDisconnectFunc func,
+							gpointer user_data);
+
 GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type);
 
 GObex *g_obex_ref(GObex *obex);
diff --git a/unit/test-gobex.c b/unit/test-gobex.c
index 48addbf..2ce5e2e 100644
--- a/unit/test-gobex.c
+++ b/unit/test-gobex.c
@@ -328,6 +328,40 @@ static void test_recv_connect_stream(void)
 	g_assert_no_error(gerr);
 }
 
+static void disconnected(GObex *obex, gpointer user_data)
+{
+	g_main_loop_quit(mainloop);
+}
+
+static void test_disconnect(void)
+{
+	GError *gerr = NULL;
+	guint timer_id;
+	GObex *obex;
+	GIOChannel *io;
+
+	create_endpoints(&obex, &io, SOCK_STREAM);
+
+	g_obex_set_disconnect_function(obex, disconnected, NULL);
+
+	timer_id = g_timeout_add_seconds(1, test_timeout, &gerr);
+
+	mainloop = g_main_loop_new(NULL, FALSE);
+
+	g_io_channel_shutdown(io, FALSE, NULL);
+
+	g_main_loop_run(mainloop);
+
+	g_assert_no_error(gerr);
+
+	g_source_remove(timer_id);
+	g_io_channel_unref(io);
+	g_obex_unref(obex);
+
+	g_main_loop_unref(mainloop);
+	mainloop = NULL;
+}
+
 static void test_ref_unref(void)
 {
 	GObex *obex;
@@ -370,6 +404,8 @@ int main(int argc, char *argv[])
 	g_test_add_func("/gobex/basic", test_basic);
 	g_test_add_func("/gobex/ref_unref", test_ref_unref);
 
+	g_test_add_func("/gobex/test_disconnect", test_disconnect);
+
 	g_test_add_func("/gobex/test_recv_connect_stream",
 						test_recv_connect_stream);
 	g_test_add_func("/gobex/test_send_connect_stream",