HP 3000 Manuals

Global RIN Program Example [ Resource Management Programmer's Guide ] MPE/iX 5.0 Documentation


Resource Management Programmer's Guide

Appendix A  Global RIN Program Example 

This HP Pascal/XL program illustrates how you can use the two intrinsics,
LOCKGLORIN and UNLOCKGLORIN, to prevent simultaneous access to a selected
record in a shared file while one user is updating the record.  Five
global RINs were previously acquired through the :GETRIN command.  Each
RIN is associated with a subset of 4 records in a 20 record data file.
This method of assigning RINs allows other users to concurrently access
other subsets of records in the same file.  RIN-locking occurs in
procedure access_record_exclusively.  This program is intended to be used
with the file BOOKFILE (illustrated in Chapter 2).

     program global_RIN_example;
     {*********************************************************************}
     {                       DECLARATION PART                              }
     {*********************************************************************}
     const
       rinbase        = 1;                   {Lowest RIN assigned          }
       recds_per_rin  = 4;                   {Partition the datafile       }
       maxrin         = 5;                   {Highest RIN assigned         }
       CCG            = 0;                   {Condition Code Warning       }
       CCL            = 1;                   {Condition Code Error         }
       CCE            = 2;                   {Condition Code successful    }
       maxbooks       =19;                   {Last record in datafile      }

     type                                    {holds titles and locations   }
       record_field   = packed array [1..36] of char;
                                             {record structure of datafile }
       library_record = packed record
                          title: record_field;     {Holds book title       }
                          location: record_field;  {Holds book location    }
                        end;

       hp_status = packed record
                   case integer of
                   0: (all:integer);
                   1: (info:shortint;        {Error number from subsys     }
                       subsys: shortint);    {Subsystem number             }
                     end;
     var
       stdin,stdlist,booklist: integer;      {HPFOPEN file numbers         }
       ascii,perm,rw,share,cctl:integer;     {HPFOPEN item variables       }
       status: hp_status;                    {HPFOPEN intrinsic status     }
       length,accno,rin: shortint;           {Vars required by intrinsics  }
       lockflag: 0..65565;                   {Required by lock intrinsics  }
       bookrecord: library_record;           {Used in read/write operations}
       dummy: boolean;                       {Required by FCONTROL         }

       infile,outfile,datafile,              {File names used with HPFOPEN }
                                             {Required by LOCKGLORIN       }
       rinpassword: packed array [1..12] of char;
                                             {vars required by intrinsics  }
       buffer,change,head,request: record_field;

     procedure hpfopen;        intrinsic;    {Opens three files            }
     function fread:shortint;  intrinsic;    {Reads from $STDIN            }
     procedure fwrite;         intrinsic;    {Writes to $STDLIST           }
     procedure fcontrol;       intrinsic;    {Post to disc                 }
     procedure freaddir;       intrinsic;    {Random reads from datafile   }
     procedure fwritedir;      intrinsic;    {Random writes to datafile    }
     procedure lockglorin;     intrinsic;    {RIN-locking intrinsic        }
     procedure unlockglorin;   intrinsic;    {RIN-unlocking intrinsic      }
     function binary:shortint; intrinsic;    {Convert ASCII to binary      }
     procedure printfileinfo;  intrinsic;    {Used in Error Handler        }
     procedure quit;           intrinsic;    {Used in Error Handler        }

     procedure error_handler(filenum,quitnum: shortint);
     {*********************************************************************}
     { procedure error_handler is invoked whenever a system intrinsic      }
     { call is unsuccessful.                                               }
     {*********************************************************************}
       begin
                                             {If valid file number, then   }
                                             {print file info to $STDLIST  }
       if filenum >=0 then printfileinfo(filenum);
       quit(quitnum);                        {Abort process                }
       end;

     procedure initialize_variables;
     {*********************************************************************}
     { procedure initialize_variables initializes all global variables     }
     { prior to use.                                                       }
     {*********************************************************************}
       begin
       infile:=  ' $stdin ';                  {associated with $STDIN      }
       outfile:= ' $stdlist ';                {associated with $STDLIST    }
       datafile:= ' bookfile ';               {formaldesignator = BOOKFILE }
       lockflag:= 1;
       rinpassword:= 'bookrin ';
       dummy:= true;
       status.all:= 0;
       ascii := 1;                           {ascii/binary option ASCII    }
       perm  := 1;                           {domain option PERMANENT      }
       rw    := 4;                           {access type option READ/WRITE}
       share := 3;                           {exclusive option SHARE       }
       cctl  := 1;                           {carriage control option CCTL }
       stdin := 0;
       stdlist := 0;
       booklist := 0;
       head:= 'LIBRARY INFORMATION PROGRAM ';  {Header introduces program  }
       change:= 'NEW LOCATION  ';              {User interface             }
       request:= 'ACCESSION NO: ';             {User interface             }
       end;

     procedure open_files;
     {*********************************************************************}
     { procedure open_files opens all files used by program.               }
     {*********************************************************************}
       begin
       hpfopen(stdin,status,2,infile,3,perm,53,ascii);     {Open $STDIN    }
       if status.all <> 0 then error_handler(-1, status.info);
       hpfopen(stdlist,status,2,outfile,3,perm,
               7,cctl,53,ascii);                           {Open $STDLIST  }
       if status.all <> 0 then error_handler(-1, status.info);
       hpfopen(booklist,status,2,datafile,
               3,perm,53,ascii,11,rw,13,share);            {Open datafile  }
       if status.all <> 0 then error_handler(-1, status.info);
       end;

     procedure select_record(var record_length: shortint;
                             var book_number: record_field);
     {*********************************************************************}
     { procedure select_record allows user to select the bookrecord for    }
     { viewing and updating.                                               }
     {*********************************************************************}
       begin
       fwrite(stdlist,request,7,208);        {Ask user for Book number     }
       if ccode <> CCE then error_handler(stdlist,101);
       record_length:= fread(stdin,buffer ,-10);   {Read user input        }
       if ccode <> CCE then error_handler(stdin,102);
       end;

     procedure update_record;
     {*********************************************************************}
     { procedure update_record prints the selected book record to $STDLIST,}
     { prompts user for new location, then reads the input from $STDIN.  If }
     { user supplies a location, record is updated, then posted to disc.   }
     {*********************************************************************}
       begin
       fwrite(stdlist,bookrecord,-72,0);     {Print selected  bookrecord   }
       if ccode <> CCE then error_handler(stdlist,105);
       fwrite(stdlist,change,-14,208);       {Prompt user for new location }
       if ccode <> CCE then error_handler(stdlist,106);
       buffer:= '                                    '; {Clear variable    }
       length:= fread(stdin,buffer,-36);     {Read user-input new location }
       if ccode <> CCE then error_handler(stdin,107);
                                             {If user input characters,    }
                                             {update record in datafile    }
       if length > 0 then
         begin
         bookrecord.location:= buffer;         {Update location field      }
         fwritedir(booklist,bookrecord,-72,accno);   {Update datafile      }
         if ccode <> CCE then error_handler(booklist,108);
         fcontrol(booklist,2,dummy);           {Force posting to disc      }
         if ccode <> CCE then error_handler (booklist,109);
         end;
       end;

     procedure access_record_exclusively(rinnum:shortint);
     {*********************************************************************}
     { procedure access_record_exclusively locks the global rin associated }
     { with the selected bookrecord.  While the RIN is locked, others       }
     { attempting to lock the same RIN are denied.  While RIN is locked,    }
     { the user-selected  book record is read from the datafile, then      }
     { PROCEDURE update_record is invoked to update the location field of  }
     { the bookrecord.  After successful update, RIN is unlocked.           }
     {*********************************************************************}
       begin
       lockglorin(rinnum,lockflag,rinpassword);  {Lock global RIN          }
       if ccode <> CCE then error_handler(-1,103);
       freaddir(booklist,bookrecord,-72,accno);  {Read selected bookrecord }
       if ccode = CCL then error_handler(booklist,104) else
       if ccode = CCE then update_record;    {Call PROCEDURE update_record }
       unlockglorin(rinnum);                 {Unlock global RIN            }
       if ccode <> CCE then error_handler(-1, 110);
       end;

     procedure update_book_information;
     {*********************************************************************}
     { procedure update_book_information is the main outer-block procedure.}
     {*********************************************************************}
       begin
       fwrite(stdlist,head,14,0);       {Print program intro to $STDLIST   }
       if ccode <> CCE then error_handler(stdlist,4);
       select_record(length,buffer);    {Call record selection procedure   }
       while length <> 0 do
                                        {Continue loop so long as user     }
                                        {selects a bookrecord to update.   }
         begin
         accno:= binary(buffer,length);    {Converts ascii to shortint     }
         if ccode <> CCE then error_handler(-1,112) else
           begin                        {If accno is successfully converted,}
                                        {use it to compute RIN.            }
           rin:= rinbase + (accno div recds_per_rin);
                                        {If computed RIN one of those from }
                                        {:GETRIN, call PROCEDURE to access }
                                        {the selected record exclusively.  }
           if rin in [rinbase..maxrin]
           then access_record_exclusively(rin);
           end;
         select_record(length,buffer);  {Select another record, loop       }
         end;                           {Loop                              }
       end;
     {*********************************************************************}
     {                          MAIN PROGRAM PART                          }
     {*********************************************************************}
     begin
     initialize_variables;
     open_files;
     update_book_information;
     end.


MPE/iX 5.0 Documentation