[rygel] renderer: Do not capture 'this' pointer in lambdas.
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] renderer: Do not capture 'this' pointer in lambdas.
- Date: Mon, 16 Mar 2015 21:42:21 +0000 (UTC)
commit 44b0b299e296a392c4a10aba8492b0b512565248
Author: Milan Plzik <milan plzik streamunlimited com>
Date: Fri Feb 20 10:27:32 2015 +0100
renderer: Do not capture 'this' pointer in lambdas.
In Vala, 'this' pointer is captures in lambdas by default. This causes issues
with a buggy C code, which depends on the order of object destruction (e.g.
AVTransport is destroyed much later than the rest of services, causing it to
use already-freed objects).
Signed-off-by: Milan Plzik <milan plzik streamunlimited com>
src/librygel-renderer/rygel-av-transport.vala | 50 +++++++++++++++++++++---
1 files changed, 43 insertions(+), 7 deletions(-)
---
diff --git a/src/librygel-renderer/rygel-av-transport.vala b/src/librygel-renderer/rygel-av-transport.vala
index 8a13d53..5fcd819 100644
--- a/src/librygel-renderer/rygel-av-transport.vala
+++ b/src/librygel-renderer/rygel-av-transport.vala
@@ -793,6 +793,25 @@ internal class Rygel.AVTransport : Service {
bool head_faked;
+ // HACK ALERT: This work around vala's feature of capturing 'this' pointer
+ // for all lambdas introduced in a class instance, even if 'this' is never
+ // used. Captured 'this' extends lifetime of an AVTransport instance beyond
+ // time expected by GUPnP. Due to GUPnP not using weak pointers at some
+ // places (e.g. xmlNode property of GUPnPServiceInfo), a crash happens when
+ // AVTransport is freed.
+ private static void setup_check_resource_callback (AVTransport instance, Soup.Message message) {
+ var weakme = WeakRef (instance);
+ var weakmsg = WeakRef (message);
+ message.got_headers.connect( () => {
+ Rygel.AVTransport? me = (Rygel.AVTransport?)weakme.get();
+ Soup.Message? msg = (Soup.Message?)weakmsg.get();
+ if (me == null || msg == null)
+ return;
+ me.head_faked = true;
+ me.session.cancel_message (msg, msg.status_code);
+ });
+ }
+
private void check_resource (Soup.Message msg,
string _uri,
string _metadata,
@@ -810,10 +829,7 @@ internal class Rygel.AVTransport : Service {
// Fake HEAD request by cancelling the message after the headers
// were received, then restart the message
- msg.got_headers.connect ((msg) => {
- this.head_faked = true;
- this.session.cancel_message (msg, msg.status_code);
- });
+ setup_check_resource_callback (this, msg);
this.session.queue_message (msg, null);
@@ -856,6 +872,27 @@ internal class Rygel.AVTransport : Service {
}
}
+ // HACK ALERT: This work around vala's feature of capturing 'this' pointer
+ // for all lambdas introduced in a class instance, even if 'this' is never
+ // used. Captured 'this' extends lifetime of an AVTransport instance beyond
+ // time expected by GUPnP. Due to GUPnP not using weak pointers at some
+ // places (e.g. xmlNode property of GUPnPServiceInfo), a crash happens when
+ // AVTransport is freed.
+ private static void setup_handle_new_transport_uri_callback(AVTransport instance,
+ Message message, string uri, string metadata, GUPnP.ServiceAction action) {
+ var weakme = WeakRef(instance);
+ var weakmsg = WeakRef(message);
+ //var weakact = WeakRef(action);
+ message.finished.connect( () => {
+ Rygel.AVTransport? me = (Rygel.AVTransport?)weakme.get();
+ Soup.Message? msg = (Soup.Message?)weakmsg.get();
+ //GUPnP.ServiceAction? act = (GUPnP.ServiceAction?)weakact.get();
+ if (me == null || msg == null)
+ return;
+ me.check_resource (msg, uri, metadata, action);
+ });
+ }
+
private void handle_new_transport_uri (ServiceAction action,
string uri,
string metadata) {
@@ -865,9 +902,8 @@ internal class Rygel.AVTransport : Service {
"1");
message.request_headers.append ("Connection", "close");
this.head_faked = false;
- message.finished.connect ((msg) => {
- this.check_resource (msg, uri, metadata, action);
- });
+ setup_handle_new_transport_uri_callback(this, message, uri,
+ metadata, action);
this.session.queue_message (message, null);
} else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]