Kednos PL/I for OpenVMS Systems
User Manual


Previous Contents Index

7.3.1.2 Defining a File's Protection

When you specify ENVIRONMENT options for a file you are creating in a PL/I program, you can specify the following options to define the access permitted to various users:

These options specify the types of access permitted by the specification of the following codes:

These codes can be specified in any order for an option; if you specify an option and omit a code, that category of user is denied that type of access. If you specify one or more protection options, the protection for unspecified categories defaults to no access. If you do not specify any protection options, then PL/I uses the current default protection for all the categories.

For example:


ENVIRONMENT (OWNER_PROTECTION ('RWE') 
            SYSTEM_PROTECTION ('R') 
            GROUP_PROTECTION('R')) 

This specification defines protection to a file as follows:

Note that the DCL command SET PROTECTION allows the owner of a file to change the file's protection at any time. Additional commands and user privileges allow the protection of a file to be overridden or changed. For details on these commands and privileges, see the OpenVMS DCL Dictionary.

The file system applies the protection you specify for a file when the file is accessed from a program or from the DCL command level. It also applies the protection when the file is to be shared.

7.3.2 File Sharing

RMS allows multiple programs to access records in the same file concurrently. The type of access is controlled by ENVIRONMENT specifications and by the current status of the file, that is, whether the file is open and, if it is open, whether it is open for input, output, or update.

The rules for sharing are as follows:

When you write a PL/I program or programs that will be sharing a file, you can specify the type of sharing. During execution of programs that share a file, RMS ensures the following:

7.3.2.1 Specifying File Sharing

In a PL/I program, you can specify one of the following file-sharing options in the ENVIRONMENT attribute:

These options indicate the type of shared operations that can be performed on the file. The defaults for these options depend on the OPEN attributes, as follows:

OPEN Attribute Default Sharing
INPUT SHARED_READ
OUTPUT NO_SHARE
UPDATE NO_SHARE

You override these defaults by specifying options for ENVIRONMENT. For example, if SHARED_READ is specified on an OPEN statement for a file opened for UPDATE, the process that opened the file is the only legal writer of the file. Other processes can access the file only for reading; they must specify SHARED_WRITE to indicate that they allow writing of the file while they are reading it.

If SHARED_WRITE is specified, processes that subsequently access the file with the SHARED_WRITE option can write the file. Both the SHARED_READ and SHARED_WRITE options can be specified for a file.

Table 7-3 summarizes the effects of opening a file with file-sharing options.

Table 7-3 Effects of File-Sharing Options
Open Option and Access Specified by First Opener Open Option Specified by a Subsequent Opener Access Allowed Subsequent Opener
     
ENV(NO_SHARE) 1
INPUT, OUTPUT,
or UPDATE
ENV(NO_SHARE)
ENV(SHARED_READ)
ENV(SHARED_WRITE)
None. The UNDEFINEDFILE condition is signaled. 2
ENV(SHARED_READ)
INPUT
ENV(NO_SHARE) None. The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_READ) The file is accessed for input.
  ENV(SHARED_WRITE) The UNDEFINEDFILE condition is signaled. 2
ENV(SHARED_READ)
OUTPUT or UPDATE
ENV(NO_SHARE) None. The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_READ) None. The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_WRITE) The file can be accessed for input only.
ENV(SHARED_WRITE)
INPUT
ENV(NO_SHARE) The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_READ) The file can be accessed for input, output, or update.
  ENV(SHARED_WRITE) The file can be accessed for input, output, or update.
ENV(SHARED_WRITE)
OUTPUT or UPDATE
ENV(NO_SHARE) None. The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_READ) None. The UNDEFINEDFILE condition is signaled. 2
  ENV(SHARED_WRITE) The file can be accessed for input, output, or update.


1You must have write access privileges to open the file with the NO_SHARE option.
2ONCODE returns the value for RMS$_FLK.

7.3.2.2 File Locking

If a file is first opened by a process in a manner that restricts sharing by other processes, RMS locks the file to prohibit access by other processes. If a PL/I procedure attempts to open a file already opened by another process for a type of access not allowed, the UNDEFINEDFILE condition is signaled. In an ON-unit that is executed for this condition, the ONCODE built-in function returns the value associated with the RMS status code RMS$_FLK (meaning that the file is locked).

In an application where files must be shared and the synchronization of sharing is important, a procedure can test whether a file is currently being accessed by another process and act accordingly. The following example illustrates an ON-unit that tests whether a file is locked:


ON UNDEFINEDFILE(STATE_FILE) BEGIN; 
  %INCLUDE $RMSDEF; 
    IF ONCODE() = RMS$_FLK 
    THEN 
       CALL WAITSYNC; 
    ELSE 
       CALL RESIGNAL(); 
END; 

This ON-unit declares the symbolic name RMS$_FLK from PLI$STARLET.TLB and uses an IF statement to verify whether the error occurred because the file is currently locked. If so, the ON-unit calls the procedure WAITSYNC, which presumably synchronizes the procedure's execution. Otherwise, it calls the RESIGNAL built-in subroutine, to request that the default PL/I ON-unit handle the UNDEFINEDFILE condition.

7.3.2.3 Record Locking

When more than one process is accessing a file at the same time, it is necessary to ensure that no process can access a record while another process is writing, rewriting, or deleting the record. To protect access to records in a shared file, PL/I use the automatic record-locking capability of RMS. Manual record locking is also available, through the record-locking options of the READ statement (LOCK_ON_READ, LOCK_ON_WRITE, MANUAL_UNLOCKING, NOLOCK, NONEXISTENT_RECORD, READ_REGARDLESS, TIMEOUT_PERIOD, and WAIT_FOR_RECORD). These manual record-locking options are valid for all file organizations.

RMS-controlled record locking in PL/I occurs, for example, when one PL/I procedure executes a READ statement (without any record-locking options specified) for a record in a file opened with the UPDATE attribute. During the execution of the READ statement, RMS automatically keeps the record locked, and no other processes can access the record until it is freed.

A record is locked when both of the following are true:

A record can also be locked by any of the following options on the READ statement:

A record remains locked until one of the following occurs:

Records are also locked for the duration of a WRITE, REWRITE, or DELETE statement to ensure that the I/O is completed. The records are unlocked when these statements are completed.

If a procedure in another process attempts to access a record that is locked, the ERROR condition is signaled. In an ON-unit that is executed once this condition exists, a reference to the ONCODE built-in function returns the value associated with the RMS status code RMS$_RLK (meaning that the record is locked).

Thus, a file-sharing application can test whether a record in a file is currently locked in an ON-unit, as in the following example:


ON ERROR BEGIN; 
    %INCLUDE $RMSDEF; 
    IF ONCODE() = RMS$_RLK 
    THEN 
        CALL RECORDSYNC(); 
    ELSE 
        CALL RESIGNAL(); 
END; 

The ON-unit in this example tests whether any ERROR condition is signaled as a result of an attempt to access a locked record. If so, the ON-unit calls a procedure that will synchronize with the other process reading the record. Otherwise, it calls the RESIGNAL built-in subroutine to perform default condition handling.

7.3.2.4 Examples of File Sharing

The following examples illustrate some of the principles of file sharing in PL/I. The procedure UPDATE_FILE obtains, modifies, and rewrites a record in a keyed file. It opens the file with the UPDATE attribute and with the ENVIRONMENT option SHARED_READ. It contains these statements:


UPDATE_FILE: PROCEDURE OPTIONS(MAIN); 
 
OPEN FILE(PARTS) RECORD UPDATE KEYED ENV( 
               SHARED_READ); 
   .
   .
   .
READ FILE(PARTS) INTO(PARTLIST) KEY(INPUT_NUM); 
   .
   .
   .
REWRITE FILE(PARTS) FROM(PARTLIST); 

The procedure PRINT_DATA reads the records in a keyed file sequentially, and displays certain fields in each record. It contains these statements:


PRINT_DATA: PROCEDURE OPTIONS(MAIN); 
OPEN FILE(PARTS) RECORD INPUT SEQUENTIAL ENV( 
                           SHARED_WRITE); 
   .
   .
   .
READ FILE(PARTS) INTO(PARTLIST); 
DO WHILE (^EOF); 
   PUT SKIP LIST(PARTLIST.NAME,QUANTITY.IN_STOCK); 
   READ FILE(PARTS) INTO(PARTLIST); 
END; 

The procedure VIEW_DATA reads the records in a keyed file sequentially, and displays certain fields in each record. It does not modify any of the records; it only needs to read them, so it uses the READ statement options READ_REGARDLESS and NOLOCK. It contains these statements:


VIEW_DATA: PROCEDURE OPTIONS(MAIN); 
OPEN FILE(PARTS) RECORD INPUT SEQUENTIAL ENV( 
                           SHARED_WRITE); 
   .
   .
   .
READ FILE(PARTS) INTO(PARTLIST) OPTIONS(READ_REGARDLESS,NOLOCK); 
DO WHILE (^EOF); 
   PUT SKIP LIST(PARTLIST.NAME,QUANTITY.IN_STOCK); 
   READ FILE(PARTS) INTO(PARTLIST) OPTIONS(READ_REGARDLESS,NOLOCK); 
END; 

For the purposes of these three examples, assume that the file PARTS is equated to the same OpenVMS file by logical name assignments so that each procedure is attempting access to the same file.

If the process running the program UPDATE_FILE is the first process to open the file, the file is opened for read sharing. When PRINT_DATA or VIEW_DATA opens the file with the SHARED_WRITE option, the file's attribute list indicates that other processes may be writing the file.

If these procedures are executing concurrently, and if, for example, UPDATE_FILE is processing a record in the file PARTS while PRINT_DATA is reading the file, it may happen that PRINT_DATA attempts access to the record being processed by UPDATE_FILE. In this case, the ERROR condition is signaled with the status code RMS$_RLK. But if VIEW_DATA attempts to read a record that is locked by UPDATE_FILE or PRINT_DATA, it can still access the record, because the READ_REGARDLESS option was specified. If VIEW_DATA is reading a record, the other two processes can still access the record, because NOLOCK was also specified as an option to the READ statement.

7.4 ENVIRONMENT Options for I/O Optimization

Many of the PL/I options for the ENVIRONMENT attribute provide optimization features for I/O operations. Table 7-4 summarizes the options that control disk file allocation. These options let you specify the space requirements of a file when you create it. Table 7-5 summarizes the options for run-time optimization of I/O processing.

Table 7-4 ENVIRONMENT Options for Optimized Disk File Creation
Option Meaning
BUCKET_SIZE Specifies the number of disk blocks per bucket, where a bucket is a unit of data storage and transfer.
CONTIGUOUS Requests that a file's extents be contiguous.
CONTIGUOUS_BEST_TRY Requests contiguous extents, if possible.
EXTENSION_SIZE Defines a default extension quantity for the file; to be used whenever the file is enlarged.
FILE_SIZE Specifies the initial number of disk blocks to be allocated for the file.

Table 7-5 ENVIRONMENT Options for Run-Time Optimization of Input/Output
Option Meaning
DEFERRED_WRITE Requests that buffers not be written out until they are full.
MULTIBLOCK_COUNT Requests multiple blocks for sequential I/O.
MULTIBUFFER_COUNT Requests multiple buffers for I/O operations.
READ_AHEAD Requests input and computation overlap for sequential input.
RETRIEVAL_POINTERS Overrides the default number of file pointers used for file access.
WRITE_BEHIND Requests output and computation overlap for sequential output.


Previous Next Contents Index