Library: OBJECT/FILEMANAGER/LIB

The following library program illustrates dynamic linkage. This library provides a set of file management routines. The users of this library assign the title of the file to be used to the LIBPARAMETER attribute. LIBPARAMETER is then used at link time to determine to which library task the user is to be linked.

          $ SHARING = PRIVATE
BEGIN
   TASK ARRAY LIBTASKS[0:10];      % PROVIDES UP TO 11 DIFFERENT LIBRARY
                                   % TASKS
   STRING ARRAY FILETITLES[0:10];  % LIBPARAMETER FOR EACH OF THE TASKS
   PROCEDURE FILEMANAGER(TASKINDEX);
   VALUE TASKINDEX;
   INTEGER TASKINDEX;
      BEGIN
      PROCEDURE READFILE;
         BEGIN
           .
           .
           .
         END READFILE;
      PROCEDURE WRITEFILE;
         BEGIN
           .
           .
         END WRITEFILE;
      EXPORT READFILE,WRITEFILE;
      FREEZE(TEMPORARY);
      FILETITLES[TASKINDEX] := ".";
      END FILEMANAGER;
   PROCEDURE SELECTION(USERSFILE,MCPCHECK);
   VALUE USERSFILE;
   EBCDIC STRING USERSFILE;
   PROCEDURE MCPCHECK(T); TASK T; FORMAL;
      BEGIN
      INTEGER TASKINDEX;
      BOOLEAN FOUND;
      % LOOK AT ALL THE FILETITLES, CHECKING TO SEE IF A LIBRARY TASK
      % HAS ALREADY BEEN INITIATED FOR FILE TITLE USERSFILE.
      WHILE NOT FOUND AND (TASKINDEX LEQ 10) DO
         BEGIN
         IF FILETITLES[TASKINDEX] = USERSFILE THEN
            FOUND := TRUE
         ELSE
            TASKINDEX := *+1;
         END;
      IF NOT FOUND THEN
         BEGIN
         % A LIBRARY TASK DOES NOT EXIST FOR THIS FILE TITLE.
         WHILE NOT FOUND DO   % FIND AN UNUSED TASK
            BEGIN
            TASKINDEX := 0;
            WHILE NOT FOUND AND (TASKINDEX LEQ 10) DO
               IF LIBTASKS[TASKINDEX].STATUS LEQ 0 THEN
                  FOUND := TRUE
               ELSE
                  TASKINDEX := *+1;
            IF NOT FOUND THEN
               % WAIT A SECOND AND MAYBE A LIBRARY TASK WILL GO TO EOT.
               WAIT((1));
            END;
         PROCESS FILEMANAGER(TASKINDEX) [LIBTASKS[TASKINDEX]];
         WHILE LIBTASKS[TASKINDEX].STATUS NEQ VALUE(FROZEN) DO
            WAIT((1));
         FILETITLES[TASKINDEX] := USERSFILE;
         END;
      MCPCHECK(LIBTASKS[TASKINDEX]);
      END SELECTION;
   PROCEDURE READFILE;
      BY CALLING SELECTION;
   PROCEDURE WRITEFILE;
      BY CALLING SELECTION;
   EXPORT READFILE,WRITEFILE;
   FREEZE(TEMPORARY);
END.

At library linkage time, the procedure SELECTION is invoked. SELECTION accepts two parameters, USERSFILE and MCPCHECK.

USERSFILE is passed the value of the LIBPARAMETER attribute, which was assigned a value by the calling program. The SELECTION procedure checks to see if a library task has been initiated for the file specified by USERSFILE. If it has, then the calling program is linked to that task. If no library task exists for that file, then a new library task is initiated and the calling program is linked to it.

Only one call is made on the SELECTION procedure per linkage; that is, all links to entry points in this library are resolved during linkage. Therefore, any changes made to any library attributes after linkage is made are ignored. The attributes can be changed if the library is delinked.

MCPCHECK is a procedure that is provided by the operating system and must be called before exiting the SELECTION procedure. The parameter to MCPCHECK is the task variable of the library task to which the calling program is to be linked. MCPCHECK verifies that the task is valid and complete. The actual library linkage is not performed until SELECTION has been exited.