Skip Menu |

This queue is for tickets about the Net-DBus CPAN distribution.

Report information
The Basics
Id: 39068
Status: resolved
Priority: 0/
Queue: Net-DBus

People
Owner: Nobody in particular
Requestors: potyl [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.33.6
Fixed in: (no value)



Subject: Reactor doesn't shutdown as soon as possible
The reactor doesn't perform the shutdown method as soon as possible. It tries to go through the pending events before it can shutdown. In some occasions the reactor will have no pending events and will perform a select. This is not very practical because even though the reactor is in 'shutdown' mode it will try to perform one last request which can make it wait forever until a file selector is ready. If a service is using the reactor then it will wait until a client connects and sends a message to then shutdown. Furthermore, the client will receive an error because his message will not be managed properly. I have a patch and a test case. Run the test case in a shell: perl shutdown-server.pl Then, in a different shell send a shutdown message to the server: dbus-send --print-reply --session --dest=org.example.HelloWorld / org.example.HelloWorld.Shutdown dbus-send --print-reply --session --dest=org.example.HelloWorld / org.example.HelloWorld.Shutdown The first call to Shutdown will fail to stop the service, while the second call will return with the following error message: Error org.freedesktop.DBus.Error.NoReply: Message did not receive a reply (timeout by message bus)
Subject: dbus-reactor.patch
--- Reactor.pm 2008-02-21 02:38:50.000000000 +0100 +++ /usr/lib/perl5/Net/DBus/Reactor.pm 2008-09-07 17:20:58.000000000 +0200 @@ -362,8 +362,15 @@ if (!$ric && !$wic && !$eic && !(defined $timeout)) { $self->{running} = 0; - return; } + + # If one of the callbacks called shutdown the reactor shouldn't wait for new + # events (select) otherwise if we have no timeouts the reactor will need to + # wait until there's a next event until it can shutdown. In the case of a + # service this means that the reactor will wait until a new message is + # received and then it will shutdown without answering to the peer! + return unless $self->{running}; + my ($ro, $wo, $eo); my $n = select($ro=$ri,$wo=$wi,$eo=$ei, (defined $timeout ? ($timeout ? $timeout/1000 : 0) : undef));
Subject: shutdown-server.pl
#!/usr/bin/perl use warnings; use strict; # # D-Bus Service with two methods: # string HelloWorld() -> Returns a greeting # void Shutdown() -> Tells the service to end # package HelloWorld; use base qw(Net::DBus::Object); use Net::DBus::Exporter qw(org.example.HelloWorld); sub new { my $class = shift; my ($service, $shutdown) = @_; my $self = $class->SUPER::new($service, "/"); bless $self, $class; $self->{shutdown} = $shutdown; return $self; } dbus_method("HelloWorld", [], ["string"]); sub HelloWorld { return "Hello world"; } dbus_method("Shutdown", [], []); sub Shutdown { my $self = shift; $self->{shutdown}->(); } package main; use Net::DBus; use Net::DBus::Reactor; my $bus = Net::DBus->session(); my $service = $bus->export_service("org.example.HelloWorld"); my $loop = Net::DBus::Reactor->main(); my $object = HelloWorld->new($service, sub {$loop->shutdown()}); $loop->run();
This patch is included in the 1.0.0 release now on CPAN.