cvsuser     02/10/07 14:55:58

  Modified:    App-Context/lib/App Context.pm
               App-Context/lib/App/Request CGI.pm
  Added:       App-Context/lib/App Authentication.pm Authorization.pm
                        CallDispatcher.pm MessageDispatcher.pm
                        ResourceLocker.pm
               App-Context/lib/App/ResourceLocker IPCLocker.pm
                        IPCSemaphore.pm
  Removed:     App-Context/lib/App LogChannel.pm Messaging.pm Procedure.pm
                        Security.pm SharedResourceSet.pm
  Log:
  renamed and reorganized
  
  Revision  Changes    Path
  1.3       +47 -6     p5ee/App-Context/lib/App/Context.pm
  
  Index: Context.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Context/lib/App/Context.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- Context.pm        18 Sep 2002 02:54:10 -0000      1.2
  +++ Context.pm        7 Oct 2002 21:55:58 -0000       1.3
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: Context.pm,v 1.2 2002/09/18 02:54:10 spadkins Exp $
  +## $Id: Context.pm,v 1.3 2002/10/07 21:55:58 spadkins Exp $
   #############################################################################
   
   package App::Context;
  @@ -771,6 +771,21 @@
       my ($self, $name, $var, $default, $setdefault) = @_;
       my ($perl, $value);
   
  +    if (!defined $var || $var eq "") {
  +        if ($name =~ /^([a-zA-Z0-9_\.-]+)([\{\}\[\]].*)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        elsif ($name =~ /^([a-zA-Z0-9_\.-]+)\.([a-zA-Z0-9_]+)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        else {
  +            $var  = $name;
  +            $name = "session";
  +        }
  +    }
  +
       if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
           $value = $self->{session}{cache}{Widget}{$name}{$var};
           if (!defined $value && defined $default) {
  @@ -800,10 +815,7 @@
               if ($App::DEBUG && $self->dbg(3));
           return $value;
       } # match {
  -    elsif ($var =~ /^([a-zA-Z0-9_\.-]+)([\{\}\[\]].*)$/) {
  -
  -        $name = $1;
  -        $var = $2;
  +    elsif ($var =~ /^[\{\}\[\]].*$/) {
   
           $self->widget($name) if (!defined $self->{session}{cache}{Widget}{$name});
   
  @@ -813,7 +825,7 @@
           print STDERR "ERROR: Context->get($var): eval ($perl): $@\n" if ($@);
   
           $self->dbgprint("Context->wget($name,$var) (indexed) = [$value]")
  -            if ($App::DEBUG && $self->dbg(3));
  +            if ($P5EEx::Blue::DEBUG && $self->dbg(3));
       }
   
       return $value;
  @@ -855,6 +867,21 @@
       $self->dbgprint("Context->wset($name,$var,$value)")
           if ($App::DEBUG && $self->dbg(3));
   
  +    if (!defined $var || $var eq "") {
  +        if ($name =~ /^([a-zA-Z0-9_\.-]+)([\{\}\[\]].*)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        elsif ($name =~ /^([a-zA-Z0-9_\.-]+)\.([a-zA-Z0-9_]+)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        else {
  +            $var  = $name;
  +            $name = "session";
  +        }
  +    }
  +
       if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
           $self->{session}{store}{Widget}{$name}{$var} = $value;
           $self->{session}{cache}{Widget}{$name}{$var} = $value
  @@ -916,6 +943,20 @@
   
       $self->dbgprint("Context->wdelete($name,$var)")
           if ($App::DEBUG && $self->dbg(3));
  +
  +    if (!defined $var || $var eq "") {
  +        if ($name =~ /^([a-zA-Z0-9_\.-]+)([\{\}\[\]].*)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        elsif ($name =~ /^([a-zA-Z0-9_\.-]+)\.([a-zA-Z0-9_]+)$/) {
  +            $name = $1;
  +            $var = $2;
  +        }
  +        else {
  +            return;
  +        }
  +    }
   
       if ($var !~ /[\[\]\{\}]/) {         # no special chars, "foo.bar"
           delete $self->{session}{store}{Widget}{$name}{$var};
  
  
  
  1.1                  p5ee/App-Context/lib/App/Authentication.pm
  
  Index: Authentication.pm
  ===================================================================
  
  #############################################################################
  ## $Id: Authentication.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::Security;
  
  use App;
  use App::Service;
  @ISA = ( "App::Service" );
  
  use strict;
  
  =head1 NAME
  
  App::Security - Interface for authentication and authorization
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $security = $context->service("Security");  # or ...
      $security = $context->security();
  
      ... TBD ...
  
  =head1 DESCRIPTION
  
  A Security service is a means by which a user may be authenticated
  and by which he may be authorized to perform specific operations.
  
  =cut
  
  #############################################################################
  # CLASS GROUP
  #############################################################################
  
  =head1 Class Group: Security
  
  The following classes might be a part of the Security Class Group.
  
  =over
  
  =item * Class: App::Security
  
  =item * Class: App::Security::Htpasswd
  
  =item * Class: App::Security::Passwd
  
  =item * Class: App::Security::DBI
  
  =item * Class: App::Security::Repository
  
  =item * Class: App::Security::SMB
  
  =item * Class: App::Security::LDAP
  
  =item * Class: App::Security::Radius
  
  =item * Class: App::Security::Kerberos
  
  =item * Class: App::Security::SSL
  
  =item * Class: App::Security::DCE
  
  =back
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::Security
  
  A Security service is a means by which a user may be authenticated
  and by which he may be authorized to perform specific operations.
  
   * Throws: App::Exception::Security
   * Since:  0.01
  
  =head2 Class Design
  
  ...
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # TBD()
  #############################################################################
  
  =head2 TBD()
  
      * Signature: $tbd_return = $repository->tbd($tbd_param);
      * Param:     $tbd_param         integer
      * Return:    $tbd_return        integer
      * Throws:    App::Exception::Repository
      * Since:     0.01
  
      Sample Usage:
  
      $tbd_return = $repository->tbd($tbd_param);
  
  =cut
  
  sub tbd {
      my ($self) = @_;
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # Method: service_type()
  #############################################################################
  
  =head2 service_type()
  
  Returns 'Security';
  
      * Signature: $service_type = App::Security->service_type();
      * Param:     void
      * Return:    $service_type  string
      * Since:     0.01
  
      $service_type = $widget->service_type();
  
  =cut
  
  sub service_type () { 'Security'; }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.1                  p5ee/App-Context/lib/App/Authorization.pm
  
  Index: Authorization.pm
  ===================================================================
  
  #############################################################################
  ## $Id: Authorization.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::LogChannel;
  
  use App;
  use App::Service;
  @ISA = ( "App::Service" );
  
  use strict;
  
  =head1 NAME
  
  App::LogChannel - Interface for logging
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $logchannel = $context->service("LogChannel");  # or ...
      $logchannel = $context->logchannel();
  
  =head1 DESCRIPTION
  
  A LogChannel service is a means by which messages are logged through a
  logging system.  This perhaps ends up in a file, or perhaps it
  ends up on someone's operator console screen somewhere.
  
  =cut
  
  #############################################################################
  # CLASS GROUP
  #############################################################################
  
  =head1 Class Group: LogChannel
  
  The following classes might be a part of the LogChannel Class Group.
  
  =over
  
  =item * Class: App::LogChannel
  
  =item * Class: App::LogChannel::LogDispatch
  
  =item * Class: App::LogChannel::NetDaemon
  
  =back
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::LogChannel
  
  A LogChannel service ...
  
   * Throws: App::Exception::LogChannel
   * Since:  0.01
  
  =head2 Class Design
  
  ...
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # log()
  #############################################################################
  
  =head2 log()
  
      * Signature: $logchannel->log(@text);
      * Param:     @text              array[string]
      * Return:    void
      * Throws:    App::Exception::LogChannel
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $logchannel = $context->service("LogChannel");  # or ...
      $logchannel->log("Error occurred");
  
  =cut
  
  sub log {
      my ($self, @text) = @_;
      print STDERR @text, "\n";
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # Method: service_type()
  #############################################################################
  
  =head2 service_type()
  
  Returns 'LogChannel';
  
      * Signature: $service_type = App::LogChannel->service_type();
      * Param:     void
      * Return:    $service_type  string
      * Since:     0.01
  
      $service_type = $widget->service_type();
  
  =cut
  
  sub service_type () { 'LogChannel'; }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.1                  p5ee/App-Context/lib/App/CallDispatcher.pm
  
  Index: CallDispatcher.pm
  ===================================================================
  
  #############################################################################
  ## $Id: CallDispatcher.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::CallDispatcher;
  
  use App;
  use App::Service;
  @ISA = ( "App::Service" );
  
  use strict;
  
  =head1 NAME
  
  App::CallDispatcher - synchronous (potentially remote) procedure invocation
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $procedure = $context->service("CallDispatcher");  # or ...
      $procedure = $context->procedure();
  
      $procedure->execute($request, $response);
      $response = $procedure->execute($request);
      $response = $procedure->execute(%named);
  
  =head1 DESCRIPTION
  
  A CallDispatcher service is a means by which a function call (perhaps remote)
  may be made synchronously.
  
  =cut
  
  #############################################################################
  # CLASS GROUP
  #############################################################################
  
  =head1 Class Group: CallDispatcher
  
  The following classes might be a part of the CallDispatcher Class Group.
  
  =over
  
  =item * Class: App::CallDispatcher
  
  =item * Class: App::CallDispatcher::Local
  
  =item * Class: App::CallDispatcher::SOAP
  
  =item * Class: App::CallDispatcher::pRPC
  
  =item * Class: App::CallDispatcher::PlRPC
  
  =item * Class: App::CallDispatcher::Messaging
  
  =back
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::CallDispatcher
  
  A CallDispatcher service is a means by which a function call (perhaps remote)
  may be made synchronously or asynchronously.
  
   * Throws: App::Exception::CallDispatcher
   * Since:  0.01
  
  =head2 Class Design
  
  ...
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # execute()
  #############################################################################
  
  =head2 execute()
  
      * Signature: $procedure->execute($request, $response);
      * Signature: $response = $procedure->execute($request);
      * Signature: $response = $procedure->execute(%named);
      * Param:     $request           ref   [in]
      * Param:     $response          ref   [out]
      * Return:    $response          ref
      * Throws:    App::Exception::CallDispatcher
      * Since:     0.01
  
      Sample Usage: 
  
      $procedure->execute($request, $response);
      $response = $procedure->execute($request);
      $response = $procedure->execute(%named);
  
  =cut
  
  sub execute {
      my $self = shift;
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # Method: service_type()
  #############################################################################
  
  =head2 service_type()
  
  Returns 'CallDispatcher';
  
      * Signature: $service_type = App::CallDispatcher->service_type();
      * Param:     void
      * Return:    $service_type  string
      * Since:     0.01
  
      $service_type = $widget->service_type();
  
  =cut
  
  sub service_type () { 'CallDispatcher'; }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.1                  p5ee/App-Context/lib/App/MessageDispatcher.pm
  
  Index: MessageDispatcher.pm
  ===================================================================
  
  #############################################################################
  ## $Id: MessageDispatcher.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::MessageDispatcher;
  
  use App;
  use App::Service;
  @ISA = ( "App::Service" );
  
  use strict;
  
  =head1 NAME
  
  App::MessageDispatcher - Interface for sending/receiving (possibly) async messages
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $messaging = $context->service("MessageDispatcher");  # or ...
      $messaging = $context->messaging();
  
      ($status, $ticket) = $messaging->send(
          recipient => $recipient,
          message => $message
      );
  
      $message = $messaging->receive();
  
      $message = $messaging->receive(
          sender => $sender,
      );
  
      $message = $messaging->receive(
          ticket => $ticket,
      );
  
  =head1 DESCRIPTION
  
  A MessageDispatcher service is a means by which data can be sent asynchronously
  (or synchronously) to a recipient and responses can be received.
  
  Because the possibility exists for the messaging channel to be asynchronous,
  code that uses a MessageDispatcher service must code for the most complicated case
  (asynchronous).
  
  =cut
  
  #############################################################################
  # CLASS GROUP
  #############################################################################
  
  =head1 Class Group: MessageDispatcher
  
  The following classes might be a part of the MessageDispatcher Class Group.
  
  =over
  
  =item * Class: App::MessageDispatcher
  
  =item * Class: App::MessageDispatcher::Mail
  
  =item * Class: App::MessageDispatcher::SOAP
  
  =item * Class: App::MessageDispatcher::Stem
  
  =item * Class: App::MessageDispatcher::Spread
  
  =item * Class: App::MessageDispatcher::Jabber
  
  =item * Class: App::MessageDispatcher::PVM
  
  =item * Class: App::MessageDispatcher::MPI
  
  =back
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::MessageDispatcher
  
  A MessageDispatcher service is a means by which data can be sent synchronously
  or asynchronously to a recipient and responses can be received.
  
   * Throws: App::Exception::MessageDispatcher
   * Since:  0.01
  
  =head2 Class Design
  
  ...
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # send()
  #############################################################################
  
  =head2 send()
  
      * Signature: ($status, $ticket) = $messaging->send(%named);
      * Param:     recipient          string
      * Param:     message            binary
      * Return:    $status            integer
      * Return:    $ticket            string
      * Throws:    App::Exception::MessageDispatcher
      * Since:     0.01
  
      Sample Usage: 
  
      ($status, $ticket) = $messaging->send(
          recipient => "stephen.adkins\@officevision.com",
          message => "Hello.",
      );
  
  =cut
  
  sub send {
      my $self = shift;
      my %args = @_;
      my ($status, $ticket);
      ($status, $ticket);
  }
  
  #############################################################################
  # receive()
  #############################################################################
  
  =head2 receive()
  
      * Signature: $message = $messaging->receive();
      * Signature: $message = $messaging->receive(%named);
      * Param:     sender          string
      * Param:     ticket          string
      * Return:    $message        binary
      * Throws:    App::Exception::MessageDispatcher
      * Since:     0.01
  
      Sample Usage: 
  
      # receive next available message
      $message = $messaging->receive();
  
      # receive next message from sender
      $message = $messaging->receive(
          sender => "stephen.adkins\@officevision.com",
      );
  
      # receive message associated with ticket
      $message = $messaging->receive(
          ticket => "XP305-3jks37sl.f299d",
      );
  
  =cut
  
  sub receive {
      my $self = shift;
      my %args = @_;
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # Method: service_type()
  #############################################################################
  
  =head2 service_type()
  
  Returns 'MessageDispatcher'.
  
      * Signature: $service_type = App::MessageDispatcher->service_type();
      * Param:     void
      * Return:    $service_type  string
      * Since:     0.01
  
      $service_type = $widget->service_type();
  
  =cut
  
  sub service_type () { 'MessageDispatcher'; }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.1                  p5ee/App-Context/lib/App/ResourceLocker.pm
  
  Index: ResourceLocker.pm
  ===================================================================
  
  #############################################################################
  ## $Id: ResourceLocker.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::ResourceLocker;
  
  use App;
  use App::Service;
  @ISA = ( "App::Service" );
  
  use strict;
  
  =head1 NAME
  
  App::ResourceLocker - Interface for locking shared resources
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");  # or ...
      $srs = $context->shared_resource_set();
  
  =head1 DESCRIPTION
  
  A ResourceLocker service represents a collection of "advisory" (or "cooperative")
  resource locks. 
  
  =cut
  
  #############################################################################
  # CLASS GROUP
  #############################################################################
  
  =head1 Class Group: ResourceLocker
  
  The following classes might be a part of the ResourceLocker Class Group.
  
  =over
  
  =item * Class: App::ResourceLocker
  
  =item * Class: App::ResourceLocker::IPCLocker
  
  =item * Class: App::ResourceLocker::IPCSemaphore
  
  =item * Class: App::ResourceLocker::BerkeleyDB
  
  =back
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::ResourceLocker
  
  A ResourceLocker service represents a collection of "advisory" (or "cooperative")
  resource locks.  These can be used to synchronize access to and modification
  of shared resources such as are stored in a SharedDatastore.
  
   * Throws: App::Exception::ResourceLocker
   * Since:  0.01
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # lock()
  #############################################################################
  
  =head2 lock()
  
      * Signature: $resource_name = $srs->lock($resource_pool);
      * Signature: $resource_name = $srs->lock($named);
      * Param:     $resource_pool          string
      * Param:     resourcePool            string
      * Param:     nonBlocking             boolean
      * Param:     nonExclusive            boolean
      * Param:     maxWaitTimeMS           integer
      * Return:    $resource_name          string
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->lock("shmem01");
  
  The lock() method on a ResourceLocker is for the purposes of cooperative
  resource locking.
  
  =cut
  
  sub lock {
      my ($self, $arg) = @_;
      my ($resource_pool, $resource_name);
      if (ref($arg) eq "HASH") {
          $resource_pool = $arg->{resourcePool};
      }
      elsif (ref($arg) eq "") {
          $resource_pool = $arg;
      }
      return undef if (! $resource_pool);
  
      # this is a dummy implementation. it does no real locking.
      # it returns a resource name which is the same as the resource pool
  
      $resource_name = $resource_pool;
      return ($resource_name);
  }
  
  #############################################################################
  # unlock()
  #############################################################################
  
  =head2 unlock()
  
      * Signature: $srs->unlock($resource_name);
      * Param:     $resource_name          string
      * Return:    void
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->unlock("shmem01");
  
  =cut
  
  sub unlock {
      my ($self, $resource_name) = @_;
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # Method: service_type()
  #############################################################################
  
  =head2 service_type()
  
  Returns 'ResourceLocker';
  
      * Signature: $service_type = App::ResourceLocker->service_type();
      * Param:     void
      * Return:    $service_type  string
      * Since:     0.01
  
      $service_type = $widget->service_type();
  
  =cut
  
  sub service_type () { 'ResourceLocker'; }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.3       +35 -4     p5ee/App-Context/lib/App/Request/CGI.pm
  
  Index: CGI.pm
  ===================================================================
  RCS file: /cvs/public/p5ee/App-Context/lib/App/Request/CGI.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- CGI.pm    18 Sep 2002 02:54:11 -0000      1.2
  +++ CGI.pm    7 Oct 2002 21:55:58 -0000       1.3
  @@ -1,6 +1,6 @@
   
   #############################################################################
  -## $Id: CGI.pm,v 1.2 2002/09/18 02:54:11 spadkins Exp $
  +## $Id: CGI.pm,v 1.3 2002/10/07 21:55:58 spadkins Exp $
   #############################################################################
   
   package App::Request::CGI;
  @@ -233,7 +233,7 @@
           #  3. "wname{m}[1]"  variable is a "multi-level hash key" under 
$context->{widget}{$wname}
           #  4. "wname"        variable is a "multi-level hash key"
           ##########################################################
  -        my (@eventvars, $var, @values, $value, $mlhashkey, $name);
  +        my (@eventvars, $var, @values, @tmp, $value, $mlhashkey, $name);
           @eventvars = ();
           foreach $var ($cgi->param()) {
               if ($var =~ /^app\.event/) {
  @@ -245,6 +245,21 @@
               }
               else {
                   @values = $cgi->param($var);
  +                if ($#values > 0) {
  +                    @tmp = ();
  +                    foreach $value (@values) {
  +                        if ($value eq "{:delete:}") {
  +                            my $delvar = $var;
  +                            $delvar =~ s/\[\]$//;
  +                            $context->wdelete($name, $delvar);
  +                        }
  +                        else {
  +                            push(@tmp, $value);
  +                        }
  +                    }
  +                    @values = @tmp;
  +                }
  +
                   if ($var =~ s/\[\]$//) {
                       $value = [ @values ];
                   }
  @@ -257,6 +272,7 @@
                   else {
                       $value = join(",",@values);
                   }
  +
                   if ($var =~ /^([^\[\]\{\}]+)([\[\]\{\}].*)/) {
                       $context->wset($1, $2, $value);
                   }
  @@ -281,7 +297,7 @@
               }
           }
   
  -        my ($key, $fullkey, $args, @args, $event, %x, %y, $x, $y);
  +        my ($key, $fullkey, $args, $arg, @args, $event, %x, %y, $x, $y);
           foreach $key (@eventvars) {
   
               # These events come from <input type=submit> type controls
  @@ -295,7 +311,22 @@
                   if ($key =~ /\((.*)\)/) {             # look for anything inside 
parentheses
                       $args = $1;
                   }
  +                if ($args eq "") {
  +                    # do nothing, @args = ()
  +                }
  +                elsif ($args =~ /\{/) {  # } balance
  +                    foreach $arg (split(/ *, */,$args)) {
  +                        if ($arg =~ /^\{(.*)\}$/) {
  +                            push(@args, $context->wget($1));
  +                        }
  +                        else {
  +                            push(@args, $arg);
  +                        }
  +                    }
  +                }
  +                else {
                   @args = split(/ *, */,$args) if ($args ne "");
  +                }
   
                   # <input type=image name=joe> returns e.g. joe.x=20 joe.y=35
                   # these two variables get turned into one event with $x, $y added 
to the end of the @args
  
  
  
  1.1                  p5ee/App-Context/lib/App/ResourceLocker/IPCLocker.pm
  
  Index: IPCLocker.pm
  ===================================================================
  
  #############################################################################
  ## $Id: IPCLocker.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::ResourceLocker::IPCLocker;
  
  use App;
  use App::ResourceLocker;
  @ISA = ( "App::ResourceLocker" );
  
  use IPC::::Locker;
  
  use strict;
  
  =head1 NAME
  
  App::ResourceLocker::IPCLocker - locking shared resources using IPC::Locker
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");  # or ...
      $srs = $context->shared_resource_set();
  
  =head1 DESCRIPTION
  
  A ResourceLocker service represents a collection of "advisory"
  (or "cooperative")
  resource locks.  The IPCLocker implementation uses the IPC::Locker
  distribution available on CPAN.  Locking is implemented by a Locker Daemon
  (lockerd), so that locking may be effectively achieved across an entire
  network.
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::ResourceLocker::IPCLocker
  
  A ResourceLocker service represents a collection of "advisory" (or "cooperative")
  resource locks.  These can be used to synchronize access to and modification
  of shared resources such as are stored in a SharedDatastore.
  
   * Throws: App::Exception::ResourceLocker
   * Since:  0.01
  
  The ResourceLocker may be configured with the following parameters, which govern
  all locks accessed in the ResourceLocker (as per IPC::Locker).
  
      family      IPC (fifo) family to communicate with the lock server
                  INET: use TCP/IP networking
                  UNIX: use Unix named pipes (created with "mknod p /path/to/fifo")
                  default: INET
      host        default: localhost (only needed for INET family)
      port        default for INET: 1751 (or as defined in /etc/services for "lockerd")
                  default for UNIX: /var/locks/lockerd
      timeout     Time at which the server will release the lock if not explicitly
                  unlocked by then
                  default: 600 sec (10 min) (0 is "unlimited")
      autounlock  Allow the locker daemon to break the lock if the locking process
                  is no longer running. (Note that there is an implicit promise
                  that the locking process is running on the same server as the
                  locker daemon.)
      random      Lock a random resource from the pool when a pool is specified
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # lock()
  #############################################################################
  
  =head2 lock()
  
      * Signature: $resource_name = $srs->lock($resource_pool);
      * Signature: $resource_name = $srs->lock($resource_set);
      * Signature: $resource_name = $srs->lock($named);
      * Param:     $resource_pool          string
      * Param:     $resource_set           []
      * Param:     resourcePool            string
      * Param:     nonBlocking             boolean
      * Param:     nonExclusive            boolean
      * Param:     maxWaitTimeMS           integer
      * Return:    $resource_name          string
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->lock("shmem01");
  
  The lock() method on a ResourceLocker is for the purposes of cooperative
  resource locking.
  
  The "nonBlocking" option works in this implementation.
  However, all locks are exclusive (the nonExclusive option is ignored).
  The "maxWaitTimeMS" option is not yet implemented.
  
  =cut
  
  sub lock {
      my ($self, $arg) = @_;
      my ($resource_pool, $args);
  
      if (ref($arg) eq "HASH") {
          $resource_pool = $arg->{resourcePool};
          $args = $arg;
      }
      elsif (ref($arg) eq "ARRAY") {
          $resource_pool = $arg;
          $args = {};
      }
      elsif (ref($arg) eq "") {
          $resource_pool = $arg;
          $args = {};
      }
      return undef if (! $resource_pool);
  
      my (@params, $lock, $resource_names, $resource_name);
  
      # substitute the list of items in the pool for the pool name
      $resource_names = $resource_pool;
      $resource_names = $self->{resourcePool}{$resource_pool}
          if (defined $self->{resourcePool}{$resource_pool});
  
      if ($self->{random} && ref($resource_names) eq "ARRAY") {
          my (@resources, $idx, @lastresources);
          @resources = @$resource_names;
          $idx = $$ % ($#resources + 1);
          if ($idx > 0) {
              @lastresources = splice(@resources, 0, $idx);
              push(@resources, @lastresources);
              $resource_names = \@resources;
          }
      }
  
      push(@params, "lock",       $resource_names);
      push(@params, "family",     $self->{family})     if (defined $self->{family});
      push(@params, "host",       $self->{host})       if (defined $self->{host});
      push(@params, "port",       $self->{port})       if (defined $self->{port});
      push(@params, "timeout",    $self->{timeout})    if (defined $self->{timeout});
      push(@params, "autounlock", $self->{autounlock}) if (defined 
$self->{autounlock});
      # I need to investigate more what IPC::Locker does with this name
      # I may need to use "$user-$session_id"
      # The default "name" is "$hostname-$pid" or something similar
      #push(@params, "user",  $self->{context}->user());
      push(@params, "block", ($args->{nonBlocking} ? 0 : 1));
  
      $lock = IPC::Locker->lock(@params);
      $resource_name = $lock->lock_name();
  
      if (defined $resource_name) {
          $self->{lock}{$resource_name} = $lock;  # save for later unlocking
      }
  
      return ($resource_name);
  }
  
  #############################################################################
  # unlock()
  #############################################################################
  
  =head2 unlock()
  
      * Signature: $srs->unlock($resource_name);
      * Param:     $resource_name          string
      * Return:    void
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->unlock("shmem01");
  
  =cut
  
  sub unlock {
      my ($self, $resource_name) = @_;
      my ($lock);
      $lock = $self->{lock}{$resource_name};
      if (defined $lock) {
          $lock->unlock();
          delete $self->{lock}{$resource_name};
      }
  }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::ResourceLocker>|App::ResourceLocker>,
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  
  
  
  1.1                  p5ee/App-Context/lib/App/ResourceLocker/IPCSemaphore.pm
  
  Index: IPCSemaphore.pm
  ===================================================================
  
  #############################################################################
  ## $Id: IPCSemaphore.pm,v 1.1 2002/10/07 21:55:58 spadkins Exp $
  #############################################################################
  
  package App::ResourceLocker::IPCSemaphore;
  
  use App;
  use App::ResourceLocker;
  @ISA = ( "App::ResourceLocker" );
  
  use IPC::SysV qw(IPC_PRIVATE IPC_CREAT IPC_EXCL IPC_NOWAIT SEM_UNDO);
  use IPC::Semaphore;
  
  use strict;
  
  =head1 NAME
  
  App::ResourceLocker::IPCSemaphore - locking shared resources using IPC::Locker
  
  =head1 SYNOPSIS
  
      use App;
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");  # or ...
      $srs = $context->shared_resource_set();
  
  =head1 DESCRIPTION
  
  A ResourceLocker service represents a collection of "advisory"
  (or "cooperative")
  resource locks.  The IPCSemaphore implementation uses the IPC::Locker
  distribution available on CPAN.  Locking is implemented by a Locker Daemon
  (lockerd), so that locking may be effectively achieved across an entire
  network.
  
  =cut
  
  #############################################################################
  # CLASS
  #############################################################################
  
  =head1 Class: App::ResourceLocker::IPCSemaphore
  
  A ResourceLocker service represents a collection of "advisory"
  (or "cooperative") resource locks. 
  These can be used to synchronize access to and modification
  of shared resources such as are stored in a SharedDatastore.
  
   * Throws: App::Exception::ResourceLocker
   * Since:  0.01
  
  Generally speaking, this module only works on Unix platforms, because they
  support the System V semaphore API on which the IPC::Semaphore module
  is built.
  
  The ResourceLocker may be configured with the following parameters, which
  govern all locks accessed in the ResourceLocker (as per IPC::Semaphore).
  
      semkey      an 8-digit hex key (i.e. 0x1234FA78) uniquely identifying the
                  semaphore set (or may be "private", not shared with any other
                  processes, useful only for multi-threaded applications).
                  If the ResourceLocker needs more than one semaphore set,
                  it will allocation additional sets with keys incremented by
                  1 from this semkey.
                  default: 0x95EE10CC
      nsems       number of semaphores to get (limited by kernel settings)
                  in each semaphore set
                  default: 100
      create      boolean whether to create the semaphore set if it does not
                  exist already
                  default: 1
      mode        permissions mode with which to create the semaphore set
                  default: 0600
  
  =cut
  
  #############################################################################
  # CONSTRUCTOR METHODS
  #############################################################################
  
  =head1 Constructor Methods:
  
  =cut
  
  #############################################################################
  # new()
  #############################################################################
  
  =head2 new()
  
  The constructor is inherited from
  L<C<App::Service>|App::Service/"new()">.
  
  =cut
  
  #############################################################################
  # PUBLIC METHODS
  #############################################################################
  
  =head1 Public Methods:
  
  =cut
  
  #############################################################################
  # lock()
  #############################################################################
  
  =head2 lock()
  
      * Signature: $resource_name = $srs->lock($resource_pool);
      * Signature: $resource_name = $srs->lock($resource_set);
      * Signature: $resource_name = $srs->lock($named);
      * Param:     $resource_pool          string
      * Param:     $resource_set           []
      * Param:     resourcePool            string
      * Param:     nonBlocking             boolean
      * Param:     nonExclusive            boolean
      * Param:     maxWaitTimeMS           integer
      * Return:    $resource_name          string
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->lock("shmem01");
  
  The lock() method on a ResourceLocker is for the purposes of cooperative
  resource locking.
  
  The "nonBlocking" option works in this implementation.
  However, all locks are exclusive (the nonExclusive option is ignored).
  The "maxWaitTimeMS" option is not yet implemented.
  
  =cut
  
  sub lock {
      my ($self, $arg) = @_;
      my ($resource_pool, $args);
      if (ref($arg) eq "HASH") {
          $resource_pool = $arg->{resourcePool};
          $args = $arg;
      }
      elsif (ref($arg) eq "ARRAY") {
          $resource_pool = $arg;
          $args = {};
      }
      elsif (ref($arg) eq "") {
          $resource_pool = $arg;
          $args = {};
      }
      return undef if (! $resource_pool);
  
      my (@params, $lock, $resource_names, $resource_name);
  
      # substitute the list of items in the pool for the pool name
      $resource_names = $resource_pool;
      $resource_names = $self->{resourcePool}{$resource_pool}
          if (defined $self->{resourcePool}{$resource_pool});
  
      push(@params, "lock",       $resource_names);
      push(@params, "timeout",    $self->{timeout})    if (defined $self->{timeout});
      push(@params, "autounlock", $self->{autounlock}) if (defined 
$self->{autounlock});
      push(@params, "block",      ($args->{nonBlocking} ? 0 : 1));
  
      $lock = $self->_lock(@params);
      $resource_name = $lock->lock_name();
  
      if (defined $resource_name) {
          $self->{lock}{$resource_name} = $lock;  # save for later unlocking
      }
  
      return ($resource_name);
  }
  
  #############################################################################
  # unlock()
  #############################################################################
  
  =head2 unlock()
  
      * Signature: $srs->unlock($resource_name);
      * Param:     $resource_name          string
      * Return:    void
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $context = App->context();
      $srs = $context->service("ResourceLocker");
      $srs->unlock("shmem01");
  
  =cut
  
  sub unlock {
      my ($self, $resource_name) = @_;
      my ($lock);
      $lock = $self->{lock}{$resource_name};
      if (defined $lock) {
          $lock->unlock();
          delete $self->{lock}{$resource_name};
      }
  }
  
  #############################################################################
  # PROTECTED METHODS
  #############################################################################
  
  =head1 Protected Methods:
  
  =cut
  
  #############################################################################
  # init()
  #############################################################################
  
  =head2 init()
  
      * Signature: $self->init();
      * Param:     void
      * Return:    void
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $self->init();
  
  The init() method is called from within the constructor to allow the class
  to customize itself.
  
  =cut
  
  sub init {
      my ($self) = @_;
  
      $self->{semset} = {};
      $self->{semnum} = {};
      $self->{semset_list} = [];
      $self->{resource_name_grid} = [];
  }
  
  #############################################################################
  # allocate()
  #############################################################################
  
  =head2 allocate()
  
      * Signature: ($semset, $semnum) = $self->allocate($resource_name);
      * Param:     $resource_name    string
      * Return:    $semset           IPC::Semaphore
      * Return:    $semnum           integer
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      ($semset, $semnum) = $self->allocate($resource_name);
  
  The allocate() method is called when $self->{semset}{$resource_name} is not
  defined in order to allocate an appropriate ($semset, $semnum) pair for a
  $resource_name.
  
  =cut
  
  sub allocate {
      my ($self,$resource_name) = @_;
      my ($semset, $semnum);
  
      # check again to see if there is already a semaphore allocated
      if (defined $self->{semset}{$resource_name}) {
         $semset = $self->{semset}{$resource_name};
         $semnum = $self->{semnum}{$resource_name};
         return($semset, $semnum);
      }
  
      my ($semset_list, $resource_name_grid);
      $semset_list        = $self->{semset_list};
      $resource_name_grid = $self->{resource_name_grid};
  
      # find an available semaphore
      my ($nsemset);
      for ($nsemset = 0; $nsemset <= $#$semset_list; $nsemset++) {
          for ($semnum = 0; $semnum <= $#$semset_list; $semnum++) {
              if (!defined $resource_name_grid->[$nsemset][$semnum]) {
                  $resource_name_grid->[$nsemset][$semnum] = $resource_name;
                  $semset = $semset_list->[$nsemset];
                  $self->{semset}{$resource_name} = $semset;
                  $self->{semnum}{$resource_name} = $semnum;
                  return($semset, $semnum);
              }
          }
      }
  
      # allocate a new set of semaphores
      my ($semkey, $nsems, $create, $exclusive, $mode);
      $semkey    = ($self->{semkey}    || 0x95EE10CC);
      $semkey    = IPC_PRIVATE if ($semkey eq "private");
      $nsems     = ($self->{nsems}     || 100);
      $create    = ($self->{create}    || 1);
      $exclusive = ($self->{exclusive} || 1);
      $mode      = ($self->{mode}      || 0600);
      $mode     |= IPC_CREAT   if ($create);
      $mode     |= IPC_EXCL    if ($exclusive);
  
      $semset = IPC::Semaphore->new($semkey, $nsems, $mode);
  
      push(@$semset_list, $semset);
      $nsemset = $#$semset_list;
      $semnum = 0;  # allocate the first one
      $resource_name_grid->[$nsemset][$semnum] = $resource_name;
      $self->{semset}{$resource_name} = $semset;
      $self->{semnum}{$resource_name} = $semnum;
      return($semset, $semnum);
  }
  
  #############################################################################
  # free()
  #############################################################################
  
  =head2 free()
  
      * Signature: $self->free($resource_name);
      * Param:     $resource_name     string
      * Return:    void
      * Throws:    App::Exception::ResourceLocker
      * Since:     0.01
  
      Sample Usage: 
  
      $self->free($resource_name);
  
  The free() method frees up a resource name so that its physical semaphore
  may be reused for some other resource.
  
  =cut
  
  sub free {
      my ($self, $resource_name) = @_;
  
  }
  
  =head1 ACKNOWLEDGEMENTS
  
   * Author:  Stephen Adkins <[EMAIL PROTECTED]>
   * License: This is free software. It is licensed under the same terms as Perl 
itself.
  
  =head1 SEE ALSO
  
  L<C<App::ResourceLocker>|App::ResourceLocker>,
  L<C<App::Context>|App::Context>,
  L<C<App::Service>|App::Service>
  
  =cut
  
  1;
  
  static int semid;
  static struct sembuf lock_op, unlock_op;
  
  int start_lib_lock()
  {
     int err, i, lastpid, semnum;
     lock_op.sem_op  = -1;   /* Lock() decrements to 0 if sem value is 1  */
     lock_op.sem_flg = 0;    /* wait until semaphore available            */
     unlock_op.sem_op  = 1;  /* Unlock() increments sem value from 0 to 1 */
     unlock_op.sem_flg = 0;  /* ??? positive sem_op values never wait     */
  
     semid = semget(SEM_KEY,MAX_LOCKS,RWMODE);
     if (semid == ERROR) {
        semid = semget(SEM_KEY,MAX_LOCKS,RWMODE|IPC_CREAT);
        if (semid == ERROR)
           log(semid,"start_lib_lock():semget");
     }
     if (semid != ERROR) {
        for (semnum=0; semnum < MAX_LOCKS; semnum++) {
           lastpid = xsemctl(semid,semnum,GETPID);
           if (xkill(lastpid,NULLSIG) == ERROR) {
              if (xsemctl(semid,semnum,SETVAL,(char *) 1) == ERROR)
                 log_fcn("start_lib_lock(2):semctl",__FILE__);
           }
        }
     }
     return(semid);
  }
  
  Lock (locknum)
  int locknum;
  {
     if (dbg(LOCK))
        dbg_printf("%-5d Lock(%d)\n",getpid(),locknum);
     lock_op.sem_num = locknum;
     log(semop(semid,&lock_op,1),"Lock");
  }
  
  Unlock (locknum)
  int locknum;
  {
     if (dbg(UNLOCK))
        dbg_printf("%-5d Unlock(%d)\n",getpid(),locknum);
     unlock_op.sem_num = locknum;
     log(semop(semid,&unlock_op,1),"Unlock");
  }
  
  
  
  


Reply via email to