Category : C Source Code
Archive   : CSRC2.ZIP
Filename : INITIA.H

 
Output of file : INITIA.H contained in archive : CSRC2.ZIP
/*
* i n i t i a . h
*/

/*)LIBRARY
*/

#ifdef DOCUMENTATION

title initial Specify Initializers and Finalizers
index Specify initializers and finalizers

synopsis

#include

INITIAL
{ initial-code-block };

FINAL
{ final-code-block };

description

The macros defined in this module provide a facility for
module-specific initialization and finalization code. The code
in the initial-code-block is called as a normal C function before
main() is called; the final-code-block is called on exit, just after
wrapup().

Neither call passes any arguments.

Any number of modules in an image may independently declare
initializers or finalizers; all of them will be called at startup or
exit. However, it is impossible to predict what order the calls will
be made in, and programs should not rely on any particular ordering.

A typical use of initializers and finalizers is the following:
Suppose you have a package that supports access to some on-disk data
base; a user of the package will call a lookup and an update function.
The file containing the data base must be opened before any operations
on it can take place, and it should be closed when the program is
finished. (Assume that the package maintains some sort of resident
buffer which it must flush.) There are two conventional approaches
to solving this problem: Have the lookup and update functions check
the file on each call, and open it if necessary - which could be quite
expensive if they are very small functions, and in any case does not
solve the problem of properly closing the file - or have the main
program call an initialization and finalization function at the proper
time. The problem with this latter approach is lack of modularity -
the main program ought not to have to know that the module needs
initialization or finalization.

The solution using these macros is straightforward. The defining
module includes the calls:

INITIAL
{ open-the-data-base };

FINAL
{ flush-buffers-and-close-the-data-base };

The wrapup() function is treated like a built-in finalizer; however,
it is guaranteed to execute before any other finalizers. (The module
defining wrapup() may declare an initializer or finalizer if it
wishes; it will be treated just like all other initializers and
finalizers.)

If any finalizer (or wrapup()) calls exit(), the program exits
immediately.

Notes: Using INITIAL will declare a static function named $init$(),
and a (char *) named $init_; similarly, FINAL will declare $finl$()
and $finl_. Also, both INITIAL and FINAL generate dsect commands.
Since C provides no way to "remember" the current dsect, both macros
issue a dsect "" command when they are done, restoring the C default
dsect.

While it is a poor idea to write code that depends on the order in
which initializers and finalizers are executed, this can be useful
information to have for debugging. Execution is always in the order
that the modules involved were examined by the task builder or linker.
When the modules are named explicitly, this will just be the order in
which they were named. When the modules come from a library, it
will be extremely difficult to predict the order in which they will
be extracted and linked in.

Warning: While initializers and finalizers provide some modularity
to package initialization and finalization, they are not a panacea.
For example, if package A calls routines in package B from within
its initializers, and package B also declares initializers, the
correct functioning of a program that includes both - hence, of any
program using package A - will be problematical.

internal

The macros operate by leaving a list of (pointers to) functions to be
called in psects $INIT$ and $FINL$. In order to be able to determine
the beginning and end of these psects, the psects $INIT, $FINL,
$INIT., and $FINL., are also reserved. These psects must not actually
contain any data; they exist solely to provide well-defined endpoints
to the initialization and finalization list. The names are
consecutive in alphabetical sequence, so the Task Builder will place
them in order. The RT11 Linker, however - and the Task Builder with
the /SQ switch - place psects in the order they are encountered.
Since it impossible to predict what order the various modules will be
seen by the linking program, it is essential that EVERY module that
refers to any of these psects refer to the two related ones as well,
and in the correct order.

bugs

Requires the DECUS C dsect commands; hence, very non-portable. It
may be possible to provide the same functionality using different
techniques; if not, what's wrong with your implementation?

author

Jerry Leichter

#endif

/*
)EDITLEVEL=05
* Edit history
* 0.0 19-Jul-82 JSL Invention
* 0.1 22-Nov-82 JSL Documentation cleanups only; much of the documentation
* gets duplicated in initia.mac.
*/

#define INITIAL dsect"$init ";dsect"$init$";static char *$init_ = &$init$;dsect"$init.";dsect"";static $init$()

#define FINAL dsect"$finl ";dsect"$finl$";static char *$finl_ = &$finl$;dsect"$finl.";dsect"";static $finl$()

/*
* Sorry about the scrunched code; DECUS C has some size limits on #define
* lines that are a pain. Here's the code "in the clear":
*
* #define INITIAL dsect "$init "; \ -- Declare the dsects in the
* dsect"$init$"; \ right order
* static char *$init_ = &$init$; \ -- Pointer to the function
* dsect"$init."; \ -- Another dsect in order
* dsect""; \ -- Back to the default
* static $init$() -- Declare the function
*
* The code for FINAL is essentially the same.
*/


  3 Responses to “Category : C Source Code
Archive   : CSRC2.ZIP
Filename : INITIA.H

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/