;;; -*- Mode:Text; Base:10.; Package:User;-*-
INITIALIZATIONS                               



Introduction               28.1 An application or subsystem often must synchronize an aspect of its work
			with an event that occurs outside of its immediate control. For example, when
			the Explorer system boots, the file system wants to set up access to the local
			file band. The initialization software provides hooks within the system that
			notify applications when such events occur. Two key elements are the
			initialization form supplied by the application and the event to which the
			initialization is to be tied, which is selected by the application from a predefined
			set of events.

			The Explorer system uses initialization lists to organize and track the status of
			all the initialization routines that need to be run. Each list contains
			initialization forms whose evaluation is triggered by an event in the system.
			Several predefined initialization lists, which correspond to events that happen
			during system processing, are supported. An application can define other
			initialization-lists that have evaluations triggered by an event defined by the
			application.

			Initialization forms are added to lists incrementally. Thus, as applications are
			added to the system, the associated initialization forms are added to the
			appropriate initialization lists. This allows the initialization code to reside with
			the source code of the application rather than being built into the system. When
			the initializations are run, the forms are evaluated in the order they were added
			to the list, so the precedence is set when the application is loaded.

			Each initialization has four attributes:

                          J       Name - A string that names the initialization

                          J       Form - The Lisp form to be evaluated

                          J       Flag - The indicator of whether the form has been evaluated

                          J       Source - The source file (if any) for the initialization

			At the appointed time, the initializations are evaluated in the order that they
			were added to the initialization list.
------------------------------------------------------------------------------------------------     

Initialization            28.2 Two sets of keywords are used to support the initialization functions.
Keywords                   A separate set of keywords is used to denote the time when an initialization
			form is run. The keywords in Table 28-1 identify the various initialization
			lists. Table 28-2 identifies keywords used to denote initializaiton time.

------------------------  ------------------------------------------------------------------------   
Table 28-1 Initialization List Keywords
------------------------  ------------------------------------------------------------------------   
Keyword                     Description
----------------------      ---------------  ------------------  ----------------------       -----------------    
:once                   Identifies the initialization list sys:once-only-initialization-list. This list
		      contains initializations that need to be performed only once when the subsystem
		      is loaded and must never be done again. For example, some databases need to be
		      initialized the first time a subsystem is loaded but should not be reinitialized
		      every time a new version of the software is loaded into a currently running
		      system. This list is for such a situation. The initializations function never sees
		      this list: its when keyword defaults to :first, so normally the form is evaluated
		      only at load time and only if it has not been evaluated already.
:system                 Identifies the initialization list sys:system-initialization-list. This list is for
		      items that need to be performed before other initializations can work. Included in
		      this category are initializing the process and window systems, the file system,
		      and the network. The initializations on this list are run every time the machine
		      is cold or warm booted, as well as when the initialization is initially added to the
		      list, unless explicitly overridden by a :normal option in the keywords list. In
		      general, the system list should not be touched by user subsystems, although you
		      may occasionally need to do so.
:cold                      Identifies the initialization list sys:cold-initialization-list. This list is used for
		      items that must be run once at cold-boot time. The initializations on this list are
		      run after the ones on the system list but before the ones on the warm list. They
		      are run only once but are reset by disk-save, thus giving the appearance of being
		      run only at cold-boot time.
:warm                  Identifies the initialization list sys:warm-initialization-list. This list is used for
		      items that must be run whenever the machine is booted, including warm boots.
		      The function that prints the greeting, for example, is on this list. Unlike the cold
		      list, the warm list initializations are run regardless of their flags.
:user-application        Identifies the initialization list sys:user-application-initialization-list. This list
		      is used for items that must be run after all the other system initializations have
		      been run but before entering the read-eval-print-loop in the Lisp Listener. This
		      list should contain user application initializations needed prior to user
		      interaction.
:before-cold                  Identifies the initialization list sys:before-cold-initialization list. This list is a
		      variant of the cold list. These initializations are run before the partition is saved
		      by disk-save. They prepare the environment for a cold boot by performing such
		      actions as logging off the user and dismounting the file system. They happen
		      only once when the partition is saved, not each time it is started up.
------------------------  ------------------------------------------------------------------------   
Table 28-1 Initialization List Keywords (Continued)
------------------------  ------------------------------------------------------------------------   
Keyword                     Description
----------------------      ---------------  ------------------  ----------------------       -----------------    
:site                         Identifies the initialization list sys:site-option-initialization-list. This list is
:site-option              run every time changes are made to an item that affect the network config-
uration of the site as a whole. Again, you should have no occasion to invoke this initialization list because
it is usually invoked automatically as part of the process of configuring the machine for communication on
a network.
:full-gc                Identifies the initialization list sys:full-gc-initialization-list. This list is run
by the full-gc function immediately before garbage collecting. Initializations can be put on this list to
discard pointers to bulky objects or to turn lists into cdr-coded form so that they remain permanently
localized.
:login                      Identifies the initialization list sys:login-initialization-list. The login function
runs the login list.
:logout                     Identifies the initialization list sys:logout-initialization-list. The logout function
runs the logout list.
----------------------      ---------------  ------------------  ----------------------       -----------------    
			These initialization lists are processed in the following order:

                          1.      System initialization list

                          2.      Cold initialization list

                          3.      Warm initialization list

                          4.      User application initialization list

			User applications are free to create their own initialization lists to be run at
			their own times. Some system programs, such as the editor, have their own
			initialization list for their own purposes. See the sys:initialization-keywords 
			(paragraph 28.3, Lisp Forms Associated With Initializations) variable for more
			information.

------------------------  ------------------------------------------------------------------------   
Table 28-2 Initialization Time of Execution Keywords
------------------------  ------------------------------------------------------------------------   
Keyword                     Description
----------------------      ---------------  ------------------  ----------------------       -----------------    
:normal                      Initialization forms should not be evaluated until the time comes for this type of
		      initialization. This keyword is the default, unless the :system or :once initialization
		      list is specified.
:now                      Evaluates the initialization form now as well as adding it to the list.
:first                    Evaluates the initialization form now if it is not flagged as having already been
		      evaluated before. This keyword is the default if :system or :once is specified.
:redo                     Does not evaluate the initialization now; also sets the status flag to indicate that
		      it has not been run even if the initialization is already in the list and flagged as
		      having been run.
:head-of-list               Causes the initialization to be placed at the front of the initialization list instead
		      of at the end, which is the default.
----------------------      ---------------  ------------------  ----------------------       -----------------    
------------------------------------------------------------------------------------------------     
Lisp Forms                    28.3 The following Lisp forms are associated with initializations.
Associated With
Initializations

               add-initialization name form &optional keywords initialization-list-name                  Function
			This function adds an initialization called name with the specified form to the
			initialization list specified either by initialization-list-name or by a keyword.
			The name argument can be a string or a symbol. If the initialization list already
			contains an initialization called name, this function changes its form to form.

			The initialization-list-name argument, if specified, is a symbol that has as its
			value the initialization list. If it is unbound, it is initialized to nil and is
			given a sys:initialization-list property of t. If a keyword specifies an
			initialization list, initialization-list-name is ignored and should not be
			specified. The default is the system warm initialization list.

			Two types of keywords are allowed in keywords. The first type (those in Table
			28-1) specifies which initialization list to use. The second type (those in Table
			28-2) specifies when to evaluate the form. Although the symbols in this list are
			elements from the KEYWORD package, they are not keywords in the sense that
			they must be followed by a value. Each of these keywords is assertive in nature;
			that is, its mere presence implies a true value. If keywords from both tables are
			used, the keyword that identifies the list should precede the keyword that
			indicates when the list should be run in the list of keywords. Otherwise, the
			keyword identifying a list may override the keyword identifying when the list
			is run.

			The add-initialization function keeps each list ordered so that initializations
			added first are at the front of the list. Therefore, by controlling the order of
			execution by the order of additions, you can control explicit dependencies on the
			order of initialization. Typically, the order of additions is controlled by the
			loading order of files. The system list is the most crucially ordered of the
			predefined lists.

               sys:initialization-keywords                                                          Variable
			Each element on this list defines the keyword for one initialization list. Each
			element is a list of two or three symbols. The first is the keyword symbol that
			names the initialization list. The second is a special variable, having as a value
			the initialization list itself. The third, if present, is a keyword defining the
			default time at which initializations added to the list should be evaluated. This
			keyword should be from Table 28-2. The third element acts as a default value if
			the call to add-initialization fails to identify when the initialization should be
			run. If the third element is not present, the default value sys:normal is
			assumed.

               delete-initialization name &optional keywords initialization-list-name                     Function
			This function removes the specified initialization from the specified
			initialization list. The name argument should be a string or symbol. The keyword
			argument can be a keyword or a list of them. The only meaningful action you can
			take with this argument is to identify which initialization list should be used.
			If keyword is nil, then you should supply the symbol name of the initialization
			list as the initialization-list-name argument, which defaults to 
			'sys:warm-initialization-list.

               initializations initialization-list-name &optional redo-flag-p flag-value-p                  Function
			This function performs the initializations in the specified list. The redo-flag-p 
			argument controls whether initializations already performed are performed again:
			the default value of nil means no, and a non-nil value means yes. The flag-value-p
			argument is the value to be placed in the flag slot of an entry. If unspecified,
			this argument defaults to t, meaning that the system should remember that the
			initialization has been performed.

               reset-initializations initialization-list-name                                          Function
			This function changes the status flag of all entries in the specified list to
			indicate that they have not been run. The next time initializations with this list
			is called, all of the forms will be evaluated. The initialization-list-name argument
			should be a symbol.
------------------------------------------------------------------------------------------------     

Adding                  28.4 The following procedures use a fictitious application named gripper
Initializations            that initializes a data array whenever the system is booted. You have two
for Applications           options for having the system initialize gripper. One way is to add gripper's
			initialization to the:user-application initialization list.  

			------------------------------------------------------------------------   

			Adding gripper's initialization to the :user-application initialization list
			requires only that the application-installation procedures executes the 
			add-initialization function:

			(add-initialization "Gripper Array Initializations"
			                    '(initialize-gripper-data-array) :user-application)

			In this example, initialize-gripper-data-array is an application defined for
			creating a data array for the gripper application. Because the :user-application 
			keyword is specified, the gripper application will be initialized after the system
			initializations stabilize the system. By specifying the :now keyword in addition
			to :user-application, you could have initialized gripper immediately.

			(add-initialization "Gripper Array Initializations"
			            '(initialize-gripper-data-array) '(:user-application :now))

			Suppose, however, that you want to initialize gripper at a time other than those
			supplied by the Explorer system. To do this, you must create your own gripper
			initialization list.

			------------------------------------------------------------------------   

			Creating your own initialization list requires several steps. First, you should
			define a variable identifying the gripper initialization list:

		  (defvar gripper-initialization-list nil
		  "This variable holds all the initializations for the gripper application.")

			Although this symbol would be created automatically for you by the 
			add-initialization function, it is better coding style to have it reside in a source
			file and to provide it with a documentation string so that META-. will have a
			reference for this variable. The list is originally empty, but as you add
			initializations to it, they are consed onto the list. Now that the new list exists,
			add the forms necessary to perform the initialization by executing the 
			add-initialization function:

			(add-initialization "Gripper Array Initializations"
			                     '(initialize-gripper-data-array) nil
			                      'gripper-initialization-list)    ; Specifies the
			                                                                             ; gripper list.

			As with the previous example, initialize-gripper-data-array is a predefined
			function for creating the data array for the gripper application. 

			In this example, you have specified the actual name of the initialization list 
			gripper-initialization-list rather than using an assigned keyword that
			represents it.

			Although it is optional, you can assign a keyword to the name of your
			application's initialization list. Doing so is merely a matter of convenience. For
			example, instead of specifying the full gripper-initialization-list name as the
			value of the initialization-list-name parameter of add-initialization, you can
			assign a keyword to the name. Then, when you invoke the function, you need to
			specify nothing for the initialization-list-name parameter. Instead, use the 
			:gripper keyword just as you used the :user-application keyword in the first
			example of this paragraph.

			To add your own initialization keyword, you need only attach the keyword of
			your choice (:gripper in this case) to the list of initialization keywords:

			(push '(:gripper gripper-initialization-list sys:normal)
			                               sys:initialization-keywords)

			At this point, you have an initialization list for the gripper application, and
			you have added the necessary forms to that list. However, you must still execute
			the initialization.

			Assuming that you are not using a predefined initialization list, you must
			execute the function initializations to actually evaluate the forms on the list
			that you have created. For this example, assume that you want to initialize the 
			gripper application at the time it is invoked. If this is the case, your function
			definition for gripper would begin similar to the following:

			(defun gripper
			   (initializations 'gripper-initialization-list)
			                                 .
			                                 .
			                                 .
			)
