[Perl] Net::Dbus and thread

Daniel P. Berrange dan at berrange.com
Sat Jul 4 15:21:28 PDT 2009


On Sat, Jul 04, 2009 at 06:48:53PM +0100, Guillaume wrote:
> I am trying to use Net::DBus with threads on a perl script, and I have
> a hard time doing this.
> 
> If I create my Net::DBus::RemoteObject outside of the threads it will
> be used on, I have errors. I thus tried to create one object per
> thread, and I have the same behaviour. Here is a small example script
> and its output.
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> use threads;
> 
> my $th1 = threads->create(\&run, 1);
> my $th2 = threads->create(\&run, 2);
> 
> sleep;
> exit;
> 
> sub run {
>  my $num = shift;
>  my ($bus, $service, $purple);
> 
>  eval {$bus = Net::DBus->session};
>  if ($@) {print "th$num: Error in bus: $@\n"; threads->exit()}
> 
>  eval {$service =
>      $bus->get_service('im.pidgin.purple.PurpleService') };
>  if ($@) {print "th$num: Error in service: $@\n"; threads->exit()}
> 
>  eval {$purple =
>      $service->get_object('/im/pidgin/purple/PurpleObject',
>                            'im.pidgin.purple.PurpleInterface')};
>  if ($@) {print "th$num: Error in purple: $@\n"; threads->exit()}
> 
>  eval {$purple->connect_to_signal ('ReceivedImMsg', \&read_cb)};
>  if ($@) {print "th$num: Error in connect: $@\n"; threads->exit()}
> 
>  eval {Net::DBus::Reactor->main()->run()};
>  if ($@) {print "th$num: Error in run: $@\n"; threads->exit()}
> }
> 
> sub read_cb {
>  print scalar(@_) , ' params', "\n";
> }
> #END OF SCRIPT
> 
> So basically get bus, get service, get object, set callback and run.
> This works very well single threaded. Here is the output of this
> particular script:
> 
> th1: Error in service: Can't call method "get_interval" without a pack
> age or object reference at /usr/lib/perl5/Net/DBus/Reactor.pm line 211.
> 
> Thread 1 terminated abnormally: Can't call method "get_interval" without
> a package or object reference at /usr/lib/perl5/Net/DBus/Reactor.pm line 211.
> 
> th2: Error in service: org.freedesktop.DBus.Error.NoMemory: Not enough memory
> 
> Thread 2 terminated abnormally: main=HASH(0x9ffd850) at
> /usr/lib/perl5/threads.pm line 101.
> #END OF OUTPUT
> 
> Is there a way to create the 'same' object twice, in two different
> threads? That is all I am after, as the different threads will not
> share those Net::DBus::RemoteObjects. The communication will be done
> through shared data structures which will contain only scalars.

I have never tried to use Perl threads, so I've not got any knowledge of
specific bugs in Net-DBus with threads. As I understand it though perl 
keeps all data separate between threads. Obviously Net-DBus has quite 
alot of C code to use libdbus.so, so the combination of shared C code 
and separate  Perl code per thread may be what's causing the trouble 
you have.

I think the best thing to try, is to have completely separate connections
to the bus in each thread.  The call:

  $bus = Net::DBus->session

actually re-uses an internal shared bus connection in libdbus.so. If you 
pass in the parameter 'private => 1' to Net::DBus->session, you'll get a 
100% non-shared, private connection. 

Regards,
Daniel
-- 
|: http://berrange.com/     -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://freshmeat.net/~danielpb/    -o-   http://gtk-vnc.sourceforge.net :|


More information about the dbus mailing list