summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRegis Merlino <regis.merlino@intel.com>2013-02-26 17:25:50 +0100
committerLudovic Ferrandis <ludovic.ferrandis@intel.com>2013-02-26 18:20:25 +0100
commit38e71f8a0dbdd2183b57c8f62e945021e2cd0ae4 (patch)
treeff65e9decc79cfa1c66c11a6e7f2f75adf6e1316
parenta6ba856815a40ee38a558791222976e952bf1c17 (diff)
downloaddleyna-server-38e71f8a0dbdd2183b57c8f62e945021e2cd0ae4.tar.gz
[Device] Handle unsubscribe when exiting
Signed-off-by: Regis Merlino <regis.merlino@intel.com>
-rw-r--r--lib/device.c69
-rw-r--r--lib/device.h2
-rw-r--r--lib/server.c14
-rw-r--r--lib/upnp.c17
-rw-r--r--lib/upnp.h2
5 files changed, 77 insertions, 27 deletions
diff --git a/lib/device.c b/lib/device.c
index e48c939..3972d5a 100644
--- a/lib/device.c
+++ b/lib/device.c
@@ -145,34 +145,43 @@ static void prv_count_data_new(dls_async_task_t *cb_data,
*count_data = cd;
}
+static void prv_context_unsubscribe(dls_device_context_t *ctx)
+{
+ if (ctx->timeout_id) {
+ (void) g_source_remove(ctx->timeout_id);
+ ctx->timeout_id = 0;
+ }
+
+ if (ctx->subscribed) {
+ gupnp_service_proxy_remove_notify(
+ ctx->service_proxy,
+ DLS_SYSTEM_UPDATE_VAR,
+ prv_system_update_cb,
+ ctx->device);
+ gupnp_service_proxy_remove_notify(
+ ctx->service_proxy,
+ DLS_CONTAINER_UPDATE_VAR,
+ prv_container_update_cb,
+ ctx->device);
+ gupnp_service_proxy_remove_notify(
+ ctx->service_proxy,
+ DLS_LAST_CHANGE_VAR,
+ prv_last_change_cb,
+ ctx->device);
+
+ gupnp_service_proxy_set_subscribed(ctx->service_proxy,
+ FALSE);
+
+ ctx->subscribed = FALSE;
+ }
+}
+
static void prv_context_delete(gpointer context)
{
dls_device_context_t *ctx = context;
if (ctx) {
- if (ctx->timeout_id)
- (void) g_source_remove(ctx->timeout_id);
-
- if (ctx->subscribed) {
- gupnp_service_proxy_remove_notify(
- ctx->service_proxy,
- DLS_SYSTEM_UPDATE_VAR,
- prv_system_update_cb,
- ctx->device);
- gupnp_service_proxy_remove_notify(
- ctx->service_proxy,
- DLS_CONTAINER_UPDATE_VAR,
- prv_container_update_cb,
- ctx->device);
- gupnp_service_proxy_remove_notify(
- ctx->service_proxy,
- DLS_LAST_CHANGE_VAR,
- prv_last_change_cb,
- ctx->device);
-
- gupnp_service_proxy_set_subscribed(ctx->service_proxy,
- FALSE);
- }
+ prv_context_unsubscribe(ctx);
if (ctx->device_proxy)
g_object_unref(ctx->device_proxy);
@@ -233,6 +242,20 @@ void dls_device_delete(void *device)
}
}
+void dls_device_unsubscribe(void *device)
+{
+ unsigned int i;
+ dls_device_t *dev = device;
+ dls_device_context_t *context;
+
+ if (dev) {
+ for (i = 0; i < dev->contexts->len; ++i) {
+ context = g_ptr_array_index(dev->contexts, i);
+ prv_context_unsubscribe(context);
+ }
+ }
+}
+
static void prv_last_change_decode(GUPnPCDSLastChangeEntry *entry,
GVariantBuilder *array,
const char *root_path)
diff --git a/lib/device.h b/lib/device.h
index 5b5705a..ef3e3df 100644
--- a/lib/device.h
+++ b/lib/device.h
@@ -63,6 +63,8 @@ dls_device_context_t *dls_device_append_new_context(dls_device_t *device,
GUPnPDeviceProxy *proxy);
void dls_device_delete(void *device);
+void dls_device_unsubscribe(void *device);
+
dls_device_t *dls_device_new(
dleyna_connector_id_t connection,
GUPnPDeviceProxy *proxy,
diff --git a/lib/server.c b/lib/server.c
index 7837e23..f09e238 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -1148,12 +1148,11 @@ static void prv_control_point_initialize(const dleyna_connector_t *connector,
g_set_prgname(DLS_PRG_NAME);
}
-static void prv_control_point_free(void)
+static void prv_control_point_finalize(void)
{
- dls_upnp_delete(g_context.upnp);
+ dls_upnp_unsubscribe(g_context.upnp);
- if (g_context.watchers)
- g_hash_table_unref(g_context.watchers);
+ dls_upnp_delete(g_context.upnp);
if (g_context.connection) {
if (g_context.dls_id)
@@ -1163,6 +1162,12 @@ static void prv_control_point_free(void)
}
}
+static void prv_control_point_free(void)
+{
+ if (g_context.watchers)
+ g_hash_table_unref(g_context.watchers);
+}
+
static const gchar *prv_control_point_server_name(void)
{
return DLEYNA_SERVER_NAME;
@@ -1180,6 +1185,7 @@ static const gchar *prv_control_point_root_introspection(void)
static const dleyna_control_point_t g_control_point = {
prv_control_point_initialize,
+ prv_control_point_finalize,
prv_control_point_free,
prv_control_point_server_name,
prv_control_point_server_introspection,
diff --git a/lib/upnp.c b/lib/upnp.c
index 0104470..a39217d 100644
--- a/lib/upnp.c
+++ b/lib/upnp.c
@@ -1046,6 +1046,23 @@ on_error:
DLEYNA_LOG_DEBUG("Exit failure");
}
+void dls_upnp_unsubscribe(dls_upnp_t *upnp)
+{
+ GHashTableIter iter;
+ gpointer value;
+ dls_device_t *device;
+
+ DLEYNA_LOG_DEBUG("Enter");
+
+ g_hash_table_iter_init(&iter, upnp->server_udn_map);
+ while (g_hash_table_iter_next(&iter, NULL, &value)) {
+ device = value;
+ dls_device_unsubscribe(device);
+ }
+
+ DLEYNA_LOG_DEBUG("Exit");
+}
+
static gboolean prv_device_uc_find(gpointer key, gpointer value,
gpointer user_data)
{
diff --git a/lib/upnp.h b/lib/upnp.h
index 8feda37..dfe2d1b 100644
--- a/lib/upnp.h
+++ b/lib/upnp.h
@@ -101,6 +101,8 @@ void dls_upnp_create_playlist_in_any(dls_upnp_t *upnp, dls_client_t *client,
dls_task_t *task,
dls_upnp_task_complete_t cb);
+void dls_upnp_unsubscribe(dls_upnp_t *upnp);
+
gboolean dls_upnp_device_context_exist(dls_device_t *device,
dls_device_context_t *context);