summaryrefslogtreecommitdiff
path: root/Ivy.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Ivy.pm')
-rw-r--r--Ivy.pm258
1 files changed, 133 insertions, 125 deletions
diff --git a/Ivy.pm b/Ivy.pm
index 9ca3875..4810a4f 100644
--- a/Ivy.pm
+++ b/Ivy.pm
@@ -4,16 +4,16 @@
# Copyright 1997-2000
# Centre d'Études de la Navigation Aérienne
#
-# Authors: Alexandre Bustico <bustico@tls.cena.fr>
-# Stéphane Chatty <chatty@tls.cena.fr>
-# Hervé Damiano <damiano@tls.cena.fr>
+# Authors: Alexandre Bustico <bustico@cena.fr>
+# Stéphane Chatty <chatty@cena.fr>
+# Hervé Damiano <damiano@cena.fr>
#
# All functions
#
# $Id$
#
-# Please refer to the debian/copyright file for the
-# copyright notice regarding this software
+# Please refer to the debian/copyright file for the
+# copyright notice regarding this software
#
package Ivy ;
@@ -25,7 +25,7 @@ use Time::Gettimeofday ;
use vars qw($VERSION);
-$VERSION = '4.3';
+$VERSION = '4.4';
#############################################################################
#### PROTOTYPES #####
@@ -263,7 +263,7 @@ use constant appName => $constantIndexer++;
use constant messWhenReady => $constantIndexer++;
#############################################################################
-#### METHODES PUBLIQUES #####
+#### METHODES PUBLIQUES #####
#############################################################################
sub init ($%)
{
@@ -271,9 +271,11 @@ sub init ($%)
# valeurs par defaut pour le parametre : variable d'environnement
# ou valeur cablee, a defaut
- my $default_ivyBus = defined $ENV{"IVYBUS"} ? $ENV{"IVYBUS"} : "";
+ my $default_ivyBus = defined $ENV{"IVYBUS"} ?
+ $ENV{"IVYBUS"} :
+ BROADCAST_ADDRS.':'.BROADCAST_PORT;
- my %defaultOptions = ( #PARAMETRES OBLIGATOIRES
+ my %optionsAndDefaults = ( #PARAMETRES OBLIGATOIRES
-loopMode => undef,
# TK ou LOCAL
@@ -308,49 +310,51 @@ sub init ($%)
# ces sujets sont eliminees.
) ;
-
- foreach my $opt (keys %defaultOptions) {
- # si un parametre n'a pas ete defini
+ # on examine toutes les options possibles
+ foreach my $opt (keys %optionsAndDefaults) {
+ # si un parametre a ete fourni, ignorer les valeurs par defaut
next if defined $options{$opt} ;
- # est-il facultatif
- if (defined $defaultOptions{$opt}) {
- $options{$opt} = $defaultOptions{$opt} ;
- }
- else {
- # parametre obligatoire
- die "ERREUR Ivy::init vous devez specifier ".
- "l'option $opt\n";
+ # sinon, prendre la valeur par defaut si elle existe
+ if (defined $optionsAndDefaults{$opt}) {
+ $options{$opt} = $optionsAndDefaults{$opt} ;
+ # sinon, on jette l'eponge
+ } else {
+ die "Error in Ivy::init: option $opt is mandatory\n";
}
}
- foreach my $opt (keys %options) {
- die "ERREUR Ivy::init option $opt inconnue\n" unless
- exists ($defaultOptions{$opt});
+ # on examine toutes les options fournies, pour detecter les inutiles
+ foreach my $opt (keys %options) {
+ unless (exists ($optionsAndDefaults{$opt})) {
+ warn "Warning in Ivy::init: option $opt is unknown\n";
+ }
}
- my $loopMode = $options{-loopMode};
- $ivyBus = $options{-ivyBus} ne "" ? $options{-ivyBus} : undef;
- $appName = $options{-appName} ;
- $messWhenReady =
- $options{-messWhenReady} eq "_APP NAME READY" ?
- "$appName READY" : $options{-messWhenReady};
-
- $onDieFunc = $options{-onDieFunc} ;
+ my $loopMode = $options{-loopMode};
+ $ivyBus = $options{-ivyBus};
+ $appName = $options{-appName} ;
+ $onDieFunc = $options{-onDieFunc} ;
@topicRegexps = @{$options{-pruneRegexp}};
+ $messWhenReady = $options{-messWhenReady} eq "_APP NAME READY" ?
+ "$appName READY" :
+ $options{-messWhenReady};
+
if ($loopMode =~ /local/i) {
# mode boucle d'evenement locale
use IO::Select;
$fileEventFunc = \&fileEvent ;
$localLoopSel = IO::Select->new ();
+
} elsif ($loopMode =~ /tk/i) {
# mode boucle d'evenement de TK
$fileEventFunc = \&_tkFileEvent ;
+
} else {
- die "l'argument \"mainloop mode\" doit etre TK ou LOCAL\n";
+ die "Error in Ivy::init, argument loopMode must be either TK or LOCAL\n";
}
- $SIG{'PIPE'} = 'IGNORE' ;
+ $SIG{'PIPE'} = 'IGNORE' ;
}
############# METHODE DE CLASSE NEW
@@ -363,7 +367,7 @@ sub new ($%)
# on verifie que la methode de classe init ait ete appelee
unless ((defined $appName) && ($appName ne '')) {
- die "ERREUR Ivy::new vous devez initialiser le module via Ivy->init ()";
+ die "Error in Ivy::new, you should have called Ivy->init () first.";
}
# No de port tcp du serveur
@@ -432,7 +436,7 @@ sub new ($%)
$self->[buffByConn] = {};
- my %defaultOptions = (
+ my %optionsAndDefaults = (
-appName => $appName,
# nom de l'appli
@@ -477,24 +481,25 @@ sub new ($%)
) ;
- foreach my $opt (keys %defaultOptions) {
- # si un parametre n'a pas ete defini
+ # on examine toutes les options possibles
+ foreach my $opt (keys %optionsAndDefaults) {
+ # si un parametre a ete fourni, ignorer les valeurs par defaut
next if defined $options{$opt} ;
- # est-il facultatif
- if (defined $defaultOptions{$opt}) {
- $options{$opt} = $defaultOptions{$opt} ;
+ # sinon, prendre la valeur par defaut si elle existe
+ if (defined $optionsAndDefaults{$opt}) {
+ $options{$opt} = $optionsAndDefaults{$opt} ;
+ # sinon, on jette l'eponge
} else {
- # parametre obligatoire
- die "ERREUR Ivy::new vous devez specifier ".
- "l'option $opt\n";
+ die "Error in Ivy::new: option $opt is mandatory\n";
}
}
- foreach my $opt (keys %options) {
- die "ERREUR Ivy::start option $opt inconnue\n" unless
- exists ($defaultOptions{$opt});
+ # on examine toutes les options fournies, pour detecter les inutiles
+ foreach my $opt (keys %options) {
+ unless (exists ($optionsAndDefaults{$opt})) {
+ warn "Warning in Ivy::new, option $opt is unknown\n";
+ }
}
-
$self->[appName] = $options{-appName} ;
@@ -505,7 +510,7 @@ sub new ($%)
$allBuses{$self} = $self;
($self->[broadcastPort], $self->[broadcastBuses]) =
- _parseIvyBusParam ($options{-ivyBus});
+ _parseIvyBusParam ($options{-ivyBus});
return ($self);
@@ -529,12 +534,12 @@ sub DESTROY ($)
}
}
- # on clos la socket de signalisation (UDP)
+ # on clot la socket de signalisation (UDP)
# print "DBG> fermeture de supSock\n";
$self->[supSock]->close() if $self->[supSock];
delete $allBuses{$self};
- # on clos la socket de connection
+ # on clot la socket de connection
# print "DBG> fermeture de connSock\n";
$self->[connSock]->close() if $self->[connSock];
undef (@$self);
@@ -595,8 +600,8 @@ sub start ($)
foreach my $netBroadcastAddr (@{$self->[broadcastBuses]}) {
send ($self->[supSock], $bonjourMsg, 0, $netBroadcastAddr) or
- warn "Ivy::start envoi du bonjour a echoue sur : $!\n";
- }
+ warn "Warning in Ivy::start, broadcast of Hello message failed: $!\n";
+ }
# callback pour traiter la reception des bonjours
&$fileEventFunc ($self->[supSock], [\&_getBonjour, $self]) ;
@@ -744,7 +749,7 @@ sub sendDirectMsgs ($$$@)
}
return 1;
} else {
- warn "Ivy::sendDirectMsgs appli $to inconnue\n";
+ warn "Warning in Ivy::sendDirectMsgs, application $to unknown\n";
return 0;
}
}
@@ -769,7 +774,7 @@ sub sendDieTo ($$)
return 1;
}
else {
- warn "Ivy::sendDieTo appli $to inconnue\n" if $^W;
+ warn "Warning in Ivy::sendDieTo, application $to is unknown\n" if $^W;
return 0;
}
}
@@ -797,8 +802,8 @@ sub ping ($$$)
############### METHODE MAINLOOP
sub mainLoop ()
{
- die "Erreur Ivy->mainLoop, Ivy doit etre initialise en mode".
- " loopMode local\n" unless defined $localLoopSel;
+ die "Error in Ivy::mainLoop, Ivy should have been initialised with LOCAL loop mode \n"
+ unless defined $localLoopSel;
my ($fd, @ready, @allDesc);
@@ -895,8 +900,7 @@ sub fileEvent ($$;$)
unless (defined $localLoopSel) {
- die ("Erreur Ivy::fileEvent : Ivy::fileEvent n'est utilisable qu'en ".
- "mode mainLoop LOCALE\n");
+ die ("Error in Ivy::fileEvent, Ivy should have been initialised in LOCAL loop mode\n");
}
if ($cb) {
@@ -927,7 +931,7 @@ sub _getBonjour ($)
my $inetAddr = $self->[supSock]->recv ($bonjourMsg, 1024, 0);
unless (length $inetAddr) {
- warn "Attention : Ivy::_getBonjour recv error, bonjour non traite\n";
+ warn "Warning in Ivy::_getBonjour, recv error, Hello message discarded\n";
return;
}
@@ -939,14 +943,14 @@ sub _getBonjour ($)
my ($version, $peerPort) = $bonjourMsg =~ /^(\d+)\s+(\d+)/;
unless (defined ($version) && defined ($peerPort)) {
- warn "Attention : Ivy::_getBonjour format du message bonjour incorrect\n".
- "message = $bonjourMsg\n" ;
+ warn "Warning in Ivy::_getBonjour, ill-formed Hello message \"$bonjourMsg\"\n" ;
return;
}
if ($version != IVY_PROTOCOLE_VERSION) {
- warn "Attention : Ivy::_getBonjour VERSION: demande de connexion de ".
- "$peerName\n version courrante : " . IVY_PROTOCOLE_VERSION . ", recue : $version\n" ;
+ warn "Warning in Ivy::_getBonjour, connection request from ".
+ "$peerName with protocol version $version,\ncurrent version is " .
+ IVY_PROTOCOLE_VERSION . "\n" ;
return;
}
@@ -977,7 +981,8 @@ sub _getBonjour ($)
}
if ($addrInIvyBus == 0) {
- warn "bonjour de $peerName ignore, ne fait pas partie des ivyBus\n" if $^W;
+ warn "Warning: Hello message from $peerName ignored,\n".
+ "this guy is outside our emission zone\n" if $^W;
return;
}
@@ -998,8 +1003,8 @@ sub _getBonjour ($)
$self->_sendWantedRegexp ($appSock);
}
else {
- warn "Attention Ivy::_getBonjour impossible de se connecter au serveur" .
- "$peerName:$peerPort\n" ;
+ warn "Warning in Ivy::_getBonjour, connection to " .
+ "$peerName:$peerPort is impossible\n" ;
}
}
@@ -1012,12 +1017,12 @@ sub _getConnections ($)
my $appSock = $self->[connSock]->accept();
unless (defined $appSock) {
- warn "Attention Ivy::_getConnections, \$appSock not defined\n";
+ warn "Warning in Ivy::_getConnections, \$appSock not defined\n";
return;
}
else {
- printf "accepting connection from %s:%d\n",
- (gethostbyaddr ($appSock->peeraddr(),AF_INET))[0],
+# printf "accepting connection from %s:%d\n",
+# (gethostbyaddr ($appSock->peeraddr(),AF_INET))[0],
$appSock->peerport() if $^W;
}
@@ -1084,7 +1089,7 @@ sub _getMessages ($$)
(.*)/x ;
# si ca a chie on rale
- (warn "Attention Ivy::_getMessages malformated message $mess\n" and return) unless defined $type ;
+ (warn "Warning in Ivy::_getMessages, ill-formated message $mess\n" and return) unless defined $type ;
# sinon on fait en fonction du type de message
if ($type == MSG) { # M S G
@@ -1105,8 +1110,8 @@ sub _getMessages ($$)
}
else {
#_sendErrorTo ($appSock, "REEGXP ID $id inconnue");
- warn ("Attention Ivy::_getMessages reception d'un message ".
- "MSG : id $id inconnu de $senderName :\n«$mess»");
+ warn ("Warning in Ivy::_getMessages, received an unknown message ".
+ "with id $id from $senderName :\n\"$mess\"");
}
}
elsif ($type == BYE) {
@@ -1146,8 +1151,8 @@ _EOL_
}
}
elsif ($type == ERROR) { # E R R O R
- warn ("Attention Ivy::_getMessages ERREUR recue de ".
- "$senderName : «$valeurs»\n");
+ warn ("Warning in Ivy::_getMessages, error message received from ".
+ "$senderName : \"$valeurs\"\n");
}
elsif ($type == DELREGEXP) { # D E L R E G E X P
# on vire la regexp des regexps vefifier
@@ -1174,8 +1179,8 @@ _EOL_
elsif ($type == APP_NAME) {
# etat Connecte
if (($self->[appName] eq $valeurs) && $^W) {
- warn "\033[1mATTENTION : Ivy::_getMessages une instance de ".
- "$self->[appName] existe deja\033[m\n" ;
+ warn "\033[1mWarning in Ivy::_getMessages, there is already an instance of ".
+ "$self->[appName] \033[m\n" ;
}
$senderName = $valeurs;
@@ -1197,8 +1202,8 @@ _EOL_
}
else {
$self->_sendErrorTo ($appSock, "DIRECT ID $id inconnue");
- warn "Attention Ivy::_getMessages reception d'un message ".
- "DIRECT d'id $id inconnue de $senderName :\n«$mess»";
+ warn "Warning in Ivy::_getMessages, received a DIRECT message with ".
+ "unknown id $id from $senderName :\n\"$mess\"";
}
} elsif ($type == DIE) {
# il faut quitter
@@ -1215,8 +1220,8 @@ _EOL_
}
# on avertit les autres qu'on se barre
my $adr = $self->_inetAdrByName ($senderName) ;
- warn "Attention Ivy::_getMessages reception d'un ordre " .
- "de suicide de $senderName ($adr) ... exiting\n" if $^W;
+ warn "Notice in Ivy::_getMessages, received a suicide request from " .
+ "$senderName ($adr) ... exiting\n" if $^W;
# adios
Ivy::exit ();
@@ -1230,8 +1235,8 @@ _EOL_
}
else {
_$self->sendErrorTo ($appSock, "TYPE DE MESS $type inconnu");
- warn ("reception d'un message de type $type inconnu de " .
- "$senderName :\n«$mess»");
+ warn ("Warning in Ivy::_getMessages, received a message of unknown ".
+ " type $type from $senderName :\n\"$mess\"");
}
}
return 0;
@@ -1326,7 +1331,7 @@ sub _removeFileDescriptor ($$)
}
unless (defined $diedAppName) {
- warn "Ivy::__removeFileDescriptor : deconnection de NONAME\n" if $^W;
+ warn "Ivy::__removeFileDescriptor : disconnection of NONAME\n" if $^W;
return;
}
@@ -1334,7 +1339,7 @@ sub _removeFileDescriptor ($$)
keys %{$self->[cnnxion]}))[0];
unless (defined $addrInet) {
- die "ERREUR _removeFileDescriptor deconnection de $diedAppName ".
+ die "Error in Ivy::_removeFileDescriptor, disconnection of $diedAppName with ".
"addrInet not defined\n";
return;
}
@@ -1500,8 +1505,7 @@ sub _parseIvyBusParam ($)
my ($ivyNetworks, $ivyPort) = $ivyBus =~ /^(.*):(.*)/;
- die ("Erreur Ivy::_parseIvyBusParam format de l'adresse ou ".
- "no de port incorrect : $ivyBus\n")
+ die ("Error in Ivy::_parseIvyBusParam, illegal bus address format: $ivyBus\n")
unless $ivyPort =~ /^\d+$/;
my @ivyAddrInet = ();
@@ -1527,7 +1531,7 @@ sub _parseIvyBusParam ($)
# chaque 0 qui sort a gauche est remplace par un 255 a droite.
my $networkAddr = getnetbyname ($netAddr);
unless (defined $networkAddr) {
- warn ("Ivy::_parseIvyBusParam reseau inconnu : $netAddr\n");
+ warn ("Warning in Ivy::_parseIvyBusParam, network $netAddr is unknown\n");
next;
}
@@ -1541,7 +1545,7 @@ sub _parseIvyBusParam ($)
$netAddrInet = pack ("CCCC", @dummyNetAddr);
} else {
# on a deja une adresse ip, on rajoute les .255
- # a la fin s'ils ont etes omis.
+ # a la fin s'ils ont ete omis.
($netAddr .= ".255.255.255") =~ s/^((\d+\.){3}\d+).*/$1/;
$netAddrInet = inet_aton ($netAddr);
}
@@ -1580,8 +1584,8 @@ use Ivy;
=head1 DESCRIPTION
-The Ivy perl module implements a software bus to provide with an easy
-communication between applications. Messages are broadcasted as ASCII strings
+The Ivy perl module implements a software bus that provides easy
+communication between applications. Messages are broadcast as ASCII strings
over a network defined by a list of domains and a port.
Messages are received if they match a regular expressions and if your application
is on the same network as remote ones.
@@ -1612,7 +1616,7 @@ Name of your application used to identify on ivy bus.
=item B<-ivyBus =E<gt> 'domain 1,...,domain n:port number'>
A list of domains, followed by port number where to broadcast messages.
-Default is 127.255.255.255:2010
+Default is 127:2010
=item B<-messWhenReady =E<gt> 'your message when ready'>
@@ -1623,10 +1627,10 @@ messages.
=item B<-onDieFunc =E<gt> [$an_object, \&a_method, @parameters]>
-A callback or method to call when application receive die message.
-Don't make an exit in callback, ivy we'll do it for you.
+A callback or method to call when your application receive a suicide request.
+Do not call exit() in the callback, Ivy will do it for you.
-Prototype of your callback must be :
+The prototype of your callback must be as follows:
sub MyCallback {
my @parameters = @_;
@@ -1634,7 +1638,7 @@ sub MyCallback {
...
}
-Prototype of your method must be :
+The prototype of your method must be as follows:
sub MyMethod {
my ($self, @parameters) = @_;
@@ -1644,7 +1648,8 @@ sub MyMethod {
=item B<-pruneRegexp =E<gt> ['subject 1', ..., 'subject n']>
-Optimize communication using this option. Regexps which don't match these subjects are removed.
+Optimize communication using this option. Regexps
+which don't match these subjects are removed.
Example :
@@ -1656,41 +1661,42 @@ Example :
=head2 Ivy->new(...);
-Check parameters, and create an ivy bus object. You must call Ivy->init before
-this one.
+Check parameters, and create an Ivy bus object. You must call
+Ivy->init before creating a bus.
Parameters are :
=over 4
-=item B<-appName =E<gt> 'your app ivy name'>
+=item B<-appName =E<gt> 'your application name'>
-Name of your application used to identify on ivy bus.
+Name of your application used to identify it with other applications
+connected on the same bus.
=item B<-ivyBus =E<gt> 'domain 1,...,domain n:port number'>
A list of domains, followed by port number where to broadcast messages.
-Default is 127.255.255.255:2010
+Default is 127:2010
=item B<-messWhenReady =E<gt> 'your message when ready'>
-Synchronisation message sent when application is ready to receive and send
+Synchronisation message sent when your application is ready to receive and send
messages.
=item B<-onDieFunc =E<gt> [\&yourdiefunc, @parameters]>
=item B<-onDieFunc =E<gt> [$an_object, \&a_method, @parameters]>
-A callback or method to call when application receive die message.
-Don't make an exit in callback, ivy we'll do it for you.
-Prototype of your callback must be :
+A callback or method called when your application receives a suicide request.
+Do not call exit() in the callback, Ivy will do it for you.
+The prototype of your callback must be as follows:
sub MyCallback {
my @parameters = @_;
...
}
-Prototype of your method must be :
+The prototype of your method must be as follows:
sub MyMethod {
my ($self, @parameters) = @_;
@@ -1703,13 +1709,14 @@ Optimize communication using this option. Regexps which don't match these subjec
=item B<-neededApp =E<gt> ['app 1', ..., 'app n']>
-A list of application your own one needs to correctly run.
+A list of applications that your application needs present on the bus
+before running.
=item B<-statusFunc =E<gt> sub {}>
-A callback which will be called until every needed app is present on bus.
+A callback which will be called until every needed app is present on the bus.
-Your callback could be :
+Your callback could be:
sub MyCallback {
my ($present, $absent, %present) = @_;
@@ -1720,9 +1727,9 @@ Your callback could be :
}
}
-Example :
+Example:
- Ivy->new(-ivyBus => '156.255.255.255,157.255.255.255:2204',
+ Ivy->new(-ivyBus => '156,157:2204',
-onDieFunc => [\&restorecontext],
-neededApp => ["DataServer", "HMI"],
-statusFunc => \&startwhenpresents);
@@ -1731,7 +1738,7 @@ Example :
=head2 Ivy->mainLoop;
-Local main events loop. Use it if you don't use Tk library.
+Local main events loop. Use it if you don't use the Tk library.
=head2 $ivyobj->stop;
@@ -1739,7 +1746,7 @@ Local main events loop. Use it if you don't use Tk library.
=head2 $ivyobj->start;
-You must call it after you are ready to communicate through ivy bus
+You must call this after you are ready to communicate through an Ivy bus
and before you really communicate.
=head2 $ivyobj->sendMsgs(@messages);
@@ -1752,21 +1759,22 @@ Example :
=head2 $ivyobj->sendAppNameMsgs(@messages);
-Send a list of messages precedeed by ivy application name.
+Send a list of messages preceded by your application's name.
Example :
$ivyobj->sendMsgs("Hello World");
- # it will send "$appName Hello World" over ivy bus
+ # it will send "$appName Hello World" over the Ivy bus
=head2 $ivyobject->bindRegexp($regexp, [\&callback, @cb_parameters]);
=head2 $ivyobject->bindRegexp($regexp, [$an_obj, \&method, @cb_parameters]);
-Allow one to associate a message which matches a regular expression and a
-callback or method. See perlre(1), to find how to write regexps.
-Use the bracketing construct ( ... ), so that ivy perl will call
-callback with matched patterns as parameters.
+This allows you to bind a regular expression to a
+callback or method. The callback or method will be called for every
+message that matches the regexp. See perlre(1) to find how to write regexps.
+Use the bracketing construct ( ... ) so that your callback is
+called with the captured bits of text as parameters.
Example :
@@ -1774,7 +1782,7 @@ Example :
# You callback will be called with one more parameter which will be
# a number precedeed by a word, because of bracketed regexp.
-Your callback and method protos must be :
+Your callback and method must be like:
sub cb {
my ($sendername, @cb_parameters,
@@ -1800,19 +1808,19 @@ Same as bindRegexp method but Ask Alex to find what is $id.
=head2 $ivyobj->sendDieTo($to)
-send a die message to $to application name.
+Send a suicide to the application named $to.
=head2 $ivyobj->ping($to, $timeout);
-send a ping message and wait until timeout to receive a pong.
+Send a ping message and wait until timeout to receive a pong.
=head2 $after_id = $ivyobj->after($timeAfter, \@callbacks_list);
-Call a list of callbacks after $timeAfter mseconds.
+Call a list of callbacks after $timeAfter milliseconds.
=head2 $repeat_id = $ivyobj->repeat($timeAfter, \@callbacks_list);
-Repeat calls of a list of callbacks after $timeAfter mseconds.
+Have a list of callbacks repeatedly called every $timeAfter milliseconds.
=head2 $ivyobj->afterCancel($after_or_repeat_id);
@@ -1834,7 +1842,7 @@ perl(1), perlre(1)
=head1 AUTHORS
-Alexandre Bustico <bustico@tls.cena.fr>, Herve Damiano <damiano@tls.cena.fr>
+Alexandre Bustico <bustico@cena.fr>, Herve Damiano <damiano@cena.fr>
=head1 COPYRIGHT