[libnet-dbus-perl] 284/335: Add API for disconnecting from a signal (rt #52764)
Intrigeri
intrigeri at moszumanska.debian.org
Sat Mar 21 01:08:10 UTC 2015
This is an automated email from the git hooks/post-receive script.
intrigeri pushed a commit to branch experimental
in repository libnet-dbus-perl.
commit b5d0a14cbbdd43c5e719ed8c3dd8d1ae2427076c
Author: Daniel P. Berrange <dan at berrange.com>
Date: Tue Jun 28 23:08:10 2011 +0100
Add API for disconnecting from a signal (rt #52764)
---
examples/example-signal-receiver.pl | 24 +++++++-
lib/Net/DBus/RemoteObject.pm | 109 +++++++++++++++++++++++++++++-------
2 files changed, 111 insertions(+), 22 deletions(-)
diff --git a/examples/example-signal-receiver.pl b/examples/example-signal-receiver.pl
index 85b2bdc..59041ff 100644
--- a/examples/example-signal-receiver.pl
+++ b/examples/example-signal-receiver.pl
@@ -17,12 +17,30 @@ my $service = $bus->get_service("org.designfu.TestService");
my $object = $service->get_object("/org/designfu/TestService/object",
"org.designfu.TestService");
-sub hello_signal_handler {
+my $sig1;
+my $sig2;
+
+my $sig1ref = \$sig1;
+my $sig2ref = \$sig2;
+
+sub hello_signal_handler1 {
my $greeting = shift;
- print "Received hello signal with greeting '$greeting'\n";
+ print ${$sig1ref} . " Received hello signal with greeting '$greeting'\n";
+
+ unless (${$sig2ref}) {
+ $object->disconnect_from_signal("HelloSignal", ${$sig1ref});
+ }
+}
+sub hello_signal_handler2 {
+ my $greeting = shift;
+ print ${$sig2ref} . " Received hello signal with greeting '$greeting'\n";
+
+ $object->disconnect_from_signal("HelloSignal", ${$sig2ref});
+ ${$sig2ref} = undef;
}
-$object->connect_to_signal("HelloSignal", \&hello_signal_handler);
+$sig1 = $object->connect_to_signal("HelloSignal", \&hello_signal_handler1);
+$sig2 = $object->connect_to_signal("HelloSignal", \&hello_signal_handler2);
my $reactor = Net::DBus::Reactor->main();
diff --git a/lib/Net/DBus/RemoteObject.pm b/lib/Net/DBus/RemoteObject.pm
index ed9e5a5..9ff1302 100644
--- a/lib/Net/DBus/RemoteObject.pm
+++ b/lib/Net/DBus/RemoteObject.pm
@@ -85,6 +85,8 @@ sub new {
$self->{object_path} = shift;
$self->{interface} = @_ ? shift : undef;
$self->{introspected} = 0;
+ $self->{signal_handlers} = {};
+ $self->{signal_id} = 0;
bless $self, $class;
@@ -199,13 +201,15 @@ sub _introspector {
}
-=item $object->connect_to_signal($name, $coderef);
+=item my $sigid = $object->connect_to_signal($name, $coderef);
Connects a callback to a signal emitted by the object. The C<$name>
parameter is the name of the signal within the object, and C<$coderef>
is a reference to an anonymous subroutine. When the signal C<$name>
is emitted by the remote object, the subroutine C<$coderef> will be
-invoked, and passed the parameters from the signal.
+invoked, and passed the parameters from the signal. A unique C<$sigid>
+will be returned, which can be later passed to C<disconnect_from_signal>
+to remove the handler
=cut
@@ -240,23 +244,90 @@ sub connect_to_signal {
warn "signal $name in interface $interface on " . $self->get_object_path . " is deprecated";
}
- $self->get_service->
- get_bus()->
- _add_signal_receiver(sub {
- my $signal = shift;
- my $ins = $self->_introspector;
- my @params;
- if ($ins) {
- @params = $ins->decode($signal, "signals", $signal->get_member, "params");
- } else {
- @params = $signal->get_args_list;
- }
- &$code(@params);
- },
- $name,
- $interface,
- $self->{service}->get_owner_name(),
- $self->{object_path});
+ my $cb = sub {
+ my $signal = shift;
+ my $ins = $self->_introspector;
+ my @params;
+ if ($ins) {
+ @params = $ins->decode($signal, "signals", $signal->get_member, "params");
+ } else {
+ @params = $signal->get_args_list;
+ }
+
+ foreach my $handler (@{$self->{signal_handlers}->{$signal->get_member}->{handlers}}) {
+ my ($id, $cb) = @{$handler};
+ &$cb(@params);
+ }
+ };
+ if (!exists $self->{signal_handlers}->{$name}) {
+ $self->{signal_handlers}->{$name} = { cb => $cb, handlers => [] };
+ $self->get_service->
+ get_bus()->
+ _add_signal_receiver($cb,
+ $name,
+ $interface,
+ $self->{service}->get_owner_name(),
+ $self->{object_path});
+ }
+ my $sigid = ++$self->{signal_id};
+ push @{$self->{signal_handlers}->{$name}->{handlers}}, [$sigid, $code];
+ return $sigid;
+}
+
+
+=item $object->disconnect_from_signal($name, $sigid);
+
+Disconnects from a signal emitted by the object. The C<$name>
+parameter is the name of the signal within the object. The
+C<$sigid> must be the unique signal handler ID returned by
+a previous C<connect_to_signal> method call.
+
+=cut
+
+sub disconnect_from_signal {
+ my $self = shift;
+ my $name = shift;
+ my $sigid = shift;
+
+ my $ins = $self->_introspector;
+ my $interface = $self->{interface};
+ if (!$interface) {
+ if (!$ins) {
+ die "no introspection data available for '" . $self->get_object_path .
+ "', and object is not cast to any interface";
+ }
+ my @interfaces = $ins->has_signal($name);
+
+ if ($#interfaces == -1) {
+ die "no signal with name '$name' is exported in object '" .
+ $self->get_object_path . "'\n";
+ } elsif ($#interfaces > 0) {
+ warn "signal with name '$name' is exported " .
+ "in multiple interfaces of '" . $self->get_object_path . "'" .
+ "connecting to first interface only\n";
+ }
+ $interface = $interfaces[0];
+ }
+
+ my @handlers;
+ foreach my $handler (@{$self->{signal_handlers}->{$name}->{handlers}}) {
+ my ($thissigid, $cb) = @{$handler};
+ if ($thissigid != $sigid) {
+ push @handlers, $handler;
+ }
+ }
+ if (@handlers) {
+ $self->{signal_handlers}->{$name}->{handlers} = \@handlers;
+ } else {
+ $self->get_service->
+ get_bus()->
+ _remove_signal_receiver($self->{signal_handlers}->{$name}->{cb},
+ $name,
+ $interface,
+ $self->{service}->get_owner_name(),
+ $self->{object_path});
+ delete $self->{signal_handlers}->{$name};
+ }
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libnet-dbus-perl.git
More information about the Pkg-perl-cvs-commits
mailing list