Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
AtExit(3)	      User Contributed Perl Documentation	     AtExit(3)

NAME
       AtExit -	perform	exit processing	for a program or object

SYNOPSIS
	use AtExit;

	sub cleanup {
	    my @args = @_;
	    print "cleanup() executing:	args = @args\n";
	}

	## Register subroutines	to be called when this program exits

	$_ = atexit(\&cleanup, "This call was registered first");
	print "first call to atexit() returned $_\n";

	$_ = atexit("cleanup", "This call was registered second");
	print "second call to atexit() returned	$_\n";

	$_ = atexit("cleanup", "This call should've been unregistered by rmexit");
	rmexit($_)  or	warn "couldnt' unregister exit-sub $_!";

	if (@ARGV == 0)	{
	   ## Register subroutines to be called	when this lexical scope	is exited
	   my $scope1 =	AtExit->new( \&cleanup,	"Scope 1, Callback 1" );
	   {
	      ## Do the	same for this nested scope
	      my $scope2 = AtExit->new;
	      $_ = $scope2->atexit( \&cleanup, "Scope 2, Callback 1" );
	      $scope1->atexit( \&cleanup, "Scope 1, Callback 2");
	      $scope2->atexit( \&cleanup, "Scope 2, Callback 2"	);
	      $scope2->rmexit($_) or warn "couldn't unregister exit-sub	$_!";

	      print "*** Leaving Scope 2 ***\n";
	    }
	    print "*** Finished	Scope 2	***\n";
	    print "*** Leaving Scope 1 ***\n";
	}
	print "*** Finished Scope 1 ***\n"  if (@ARGV == 0);

	END {
	    print "*** Now performing program-exit processing ***\n";
	}

DESCRIPTION
       The AtExit module provides ANSI-C style exit processing modeled after
       the "atexit" function in	the standard C library (see atexit(3C)).
       Various exit processing routines	may be registered by calling atexit
       and passing it the desired subroutine along with	any desired arguments.
       Then, at	program-exit time, the subroutines registered with atexit are
       invoked with their given	arguments in the reverse order of registration
       (last one registered is invoked first).	Registering the	same
       subroutine more than once will cause that subroutine to be invoked once
       for each	registration.

       An AtExit object	can be created in any scope. When invoked as a
       function, atexit	registers callbacks to be executed at program-exit
       time. But when invoked as an object-method (using the
       "$object->method_name" syntax), callbacks registered with an AtExit
       object are executed at object-destruction time! The rules for order of
       execution of the	registered subroutines are the same for	objects	during
       object-destruction, as for the program during program-termination.

       The atexit function/method should be passed a subroutine	name or
       reference, optionally followed by the list of arguments with which to
       invoke it at program/object exit	time.  Anonymous subroutine references
       passed to atexit	act as "closures" (which are described in perlref).
       If a subroutine name is specified (as opposed to	a subroutine
       reference) then,	unless the subroutine name has an explicit package
       prefix, it is assumed to	be the name of a subroutine in the caller's
       current package.	 A reference to	the specified subroutine is obtained,
       and, if invocation arguments were specified, it is "wrapped up" in a
       closure which invokes the subroutine with the specified arguments.  The
       resulting subroutine reference is added to the front of the list	of
       exit-handling subroutines for the program ("atexit") or the AtExit
       object ("$exitObject->atexit") and the reference	is then	returned to
       the caller (just	in case	you might want to unregister it	later using
       rmexit. If the given subroutine could not be registered,	then the value
       zero is returned.

       The rmexit function/method should be passed one or more subroutine
       references, each	of which was returned by a previous call to atexit.
       For each	argument given,	rmexit will look in the	list of	exit-handling
       subroutines for the program (rmexit) or the AtExit object
       ("$exitObject->rmexit") and remove the first matching entry from	the
       list. If	no arguments are given,	then all program or object exit-
       handlers	are unregistered!  The value returned will be the number of
       subroutines that	were successfully unregistered.

       At object destruction time, the "DESTROY{}" subroutine in the AtExit
       module iterates over the	subroutine references in the AtExit object and
       invokes each one	in turn	(each subroutine is removed from the front of
       the queue immediately before it is invoked).  At	program-exit time, the
       "END{}" block in	the AtExit module iterates over	the subroutines	in the
       array returned by the exit_subs method and invokes each one in turn
       (each subroutine	is removed from	the front of the queue immediately
       before it is invoked).  Note that in both cases (program-exit, and
       object-destruction) the subroutines in this queue are invoked in	first-
       to-last order (the reverse order	in which they were registered with
       atexit).

   Adding and removing callbacks during	exit/destruction time.
       The method ignore_when_exiting specifies	how exit-callback registration
       and unregistration will be handled during program-exit or object-
       destruction time, while exit-callbacks are in process of	being invoked.

       When invoked as a class method (e.g., "AtExit->ignore_when_exiting"),
       ignore_when_exiting corresponds to the handling of calls	to atexit and
       rmexit during program-termination. But when invoked as an object	method
       (e.g., "$exitObject->ignore_when_exiting"), then	ignore_when_exiting
       corresponds to the handling of calls to atexit and rmexit during
       object-destruction for the particular object.

       By default, ignore_when_exiting returns a non-zero value, which causes
       atexit to ignore	any calls made to it during this time (a value of zero
       will be returned). This behavior	is consistent with that	of the
       standard	C library function of the same name. If	desired	however, the
       user may	enable the registration	of subroutines by atexit during	this
       time by invoking	ignore_when_exiting and	passing	it an argument of 0,
       "", or "undef" (for example, "AtExit->ignore_when_exiting(0)" or
       "$exitObject->ignore_when_exiting(0)", Just remember that any
       subroutines registered with atexit be placed at the front of the	queue
       of yet-to-be-invoked exit-processing subroutines	for the	program
       (atexit)	or the AtExit object ("$exitObject->atexit").

       Regardless of when it is	invoked, rmexit	will always attempt to
       unregister the given subroutines	(even when called during
       program/object exit processing).	 Keep in mind however that if it is
       invoked during program/object exit then it will fail to unregister any
       subroutines that	have already been invoked (since those subroutine
       calls have already been removed from the	corresponding list of exit-
       handling	subroutines).

       The method is_exiting may consulted examined to determine if routines
       registered using	atexit are currently in	the process of being invoked.
       It will be non-zero if they are and zero	otherwise. When	invoked	as a
       class method (e.g., "AtExit->is_exiting"), the return value will
       correspond to program-exit processing; but when invoked as an object
       method (e.g., "$exitObject->is_exiting")	the return value will
       correspond to object-destruction	processing for the given object.

       If, for any reason, the list of registered callback needs to be
       directly	accessed or manipulated, the exit_subs function	will return a
       reference to the	list of	program-exit callbacks.	When invoked as	a
       method, exit_subs will return a reference to the	list of	object-
       destruction callbacks for the corresponding object.

EXPORTS
       For backward compatibility, atexit and rmexit are exported by default.
       Note however that exit_subs, is_exiting,	and ignore_when_exiting	are
       not exported by default,	and should be invoked as class methods (e.g.
       "AtExit->is_exiting") if	they are to manipulate program-exit
       information (rather than	object-destruction) and	not explicitly
       imported.

CAVEATS
Program-termination and	Object-destruction
       The usual Perl way of doing program/module-exit processing is through
       the use of "END{}" blocks (see "Package Constructors and	Destructors"
       in perlmod).  The AtExit	module implements its program-exit processing
       with with an "END{}" block that invokes all the subroutines registered
       by atexit in the	array whose referenced is returned by "exit_subs".

       For an object, object-destruction processing is implemented by having
       the "DESTROY" method for	the object invoke all the subroutines
       registered by "$exitObject->atexit". This occurs	when the object	loses
       it's last reference, which is not necessarily at	program	end time.

       For objects defined in the global context, if any other "END{}" block
       processing is specified in the user's code or in	any other packages it
       uses, then the order in which the exit processing takes place is
       subject to Perl's rules for the order in	which objects loose their last
       references and "END{}" blocks are processed. This may affect when
       subroutines registered with atexit are invoked with respect to other
       exit processing that is to be performed.	In particular, if rmexit is
       invoked from within an "END{}" block that executes after	the AtExit
       object was destroyed, then the corresponding subroutine will not	be
       registered and will never be invoked by the AtExit module's destructor
       code.

"END{}"	block processing order
       "END{}" blocks, including those in other	packages, get called in	the
       reverse order in	which they appear in the code. (atexit subroutines get
       called in the reverse order in which they are registered.) If a package
       gets read via "use", it will act	as if the "END{}" block	was defined at
       that particular part of the "main" code.	 Packages read via "require"
       will be executed	after the code of "main" has been parsed and will be
       seen last so will execute first (they get executed in the context of
       the package in which they exist).

       It is important to note that "END{}" blocks and object destruction only
       get called on normal termination	(which includes	calls to die or
       Carp::croak). They do not get called when the program terminates
       abnormally (due to a signal for example)	unless special arrangements
       have been made by the programmer	(e.g. using a signal handler --	see
       "%SIG{expr}" in perlvar).

SEE ALSO
       atexit(3C) describes the	atexit function	for the	standard C library
       (the actual Unix	manual section in which	it appears may differ from
       platform	to platform - try sections 3C, 3, 2C, and 2).  Further
       information on anonymous	subroutines ("closures") may be	found in
       perlref.	 For more information on "END{}" blocks, see "Package
       Constructors and	Destructors" in	perlmod.  See "%SIG{expr}" in perlvar
       for handling abnormal program termination.

       The following modules all provide similar capability: Scope::OnExit,
       Scope::Cleanup, Scope::Guard, Guard, End, Perl::AtEndOfScope,
       ReleaseAction, Scope::local_OnExit, Sub::ScopeFinalizer.

       Hook::Scope provides a similar capability, but it failed	to install for
       me, and was last	released in 2003.

       Value::Canary lets you provide code to be invoked when a	value is
       destroyed.

       B::Hooks::EndOfScope will execute your code after the scope finishes
       compiling.

REPOSITORY
       <https://github.com/neilb/AtExit>

COPYRIGHT AND LICENSE
       This software is	copyright (c) 1996 by Brad Appleton.

       This is free software; you can redistribute it and/or modify it under
       the terms of the	Artistic License 1.0.

AUTHOR
       Andrew Langmead <aml@world.std.com> (initial draft).

       Brad Appleton <bradapp@enteract.com> (Version 1.02 and 2.00).

       Michael A. Chase	<mchase@ix.netcom.com> (Version	2.00).

perl v5.32.1			  2021-05-19			     AtExit(3)

NAME | SYNOPSIS | DESCRIPTION | EXPORTS | CAVEATS | Program-termination and Object-destruction | "END{}" block processing order | SEE ALSO | REPOSITORY | COPYRIGHT AND LICENSE | AUTHOR

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=AtExit&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help