• Aucun résultat trouvé

DETAILS ON USING SHARED FILES CONCURRENTLY

Dans le document The Michigan Terminal System (Page 156-160)

When discussing the use of shared files in MTS, two distinct processes are of concern. First, the process by which the owner of a file grants or denies others access to that file and subsequently the resolution involved in determining the allowable access to others; second, once access has been granted to a user, the process by which concurrent use of the shared file is controlled. The first process involves the use of the PERMIT command as well as the subsequent access resolution and is described elsewhere; only the second process is described here.

A file can be used concurrently among several tasks (jobs)1 in MTS. Although the system has hardware available to allow separate tasks to address the same virtual storage (i.e., the same copy of a file), this facility isnotused in the current mechanism for sharing files in MTS. Thus, two tasks using the same file concurrently actually address their own separate copies of the shared file.

Thus, the problem of controlling concurrent use of a shared fileamong separate tasksamounts to the bookkeeping necessary to guarantee that concurrent use will not endanger the integrity of the actual file on disk. Quite simply, this is accomplished, first, by maintaining a system-wide shared-file table of all files currently in use as well as how and by whom each file is being used and, second, by enforcing a set of rules describing exactly what types of concurrent use can be allowed at any time.

Before describing the rules of concurrent use, something should be said about opening and closing files in MTS as opposed to locking and unlocking files in MTS.

A file is opened the first time it is referenced (read, written, etc.). The opening process requires searching the appropriate file catalog, determining allowable access, allocating buffers in virtual memory for the file, and reading parts of the file from the secondary storage device (disk) into the buffers. A file is closed whenever the user or MTS indicates that the use of the file is complete.

Closing a file requires that any modified buffers be rewritten back onto secondary storage, and the buffers be deallocated. Opening and closing a file is a rather time-consuming process and needs to be done only once for each use of a file.

On the other hand, a file must be locked (in the appropriate fashion) before any operation (reading, emptying, etc.) can be performed on the file. The locking process requires that MTS interrogate the system-wide shared-file table to determine if (concurrent) use is possible at this particular time. If so, MTS records in the table how the file has been locked and by whom. A file is unlocked whenever MTS indicates that the use of the file is complete or whenever the user indicates that concurrent use of the file need no longer be restricted. The unlocking process amounts to deleting the appropriate information from the system-wide shared-file table.2The MTS file-sharing facility was designed so that the opening and closing of files is independent of the locking and unlocking of files (i.e., a file can be opened without being locked or can be locked without being opened). This is desirable, since in many

---1A task can be either a batch job, a terminal session, or a server.

2All files in MTS are potentially sharable since MTS allows concurrent signons of the same userID; thus all files must be locked and unlocked during the normal course of operation.

shared-file applications it is necessary to lock and unlock files many times during the single use of a file.

In MTS, three classes of locking are defined to maintain the integrity of a shared file. These three classes are: locking a file for reading, locking a file for modification (writing, emptying, truncating, renumbering, etc.), and locking a file for destroying (renaming, permitting). These three locking classes are inclusive in the sense that locking a file for modification also locks a file for reading, and locking a file for destroying also locks the file for modification and reading.

The rules for concurrent use of a fileamong separate taskscan now be stated in terms of the locking restrictions.

(1) Any number of tasks can have a file locked for reading at the same time as long as no other task has the file locked for modification or destroying.

(2) Only one task can have a file locked for modification at any given time, and then only if no other task has the file locked for reading or destroying.

(3) Only one task can have a file locked for destroying at any given time, and then only if no other task has the file open, or locked for reading or modification.

The process by which files are locked and unlocked falls into two categories. Files areimplicitly (automatically) locked and unlocked by MTS whenever a user requests something of MTS which requires locking. Files can also beexplicitlylocked and unlocked by the user from either the command level or the subroutine level.

Thus, if a user asks MTS to LIST a file, MTS will implicitly and automatically lock the file for reading, list the file, and then unlock the file. Likewise, if the user asks MTS to COPY informationtoa file, MTS will implicitly and automatically lock the file for modification, copy information to the file, and then unlock the file. Similarly, if the user is operating at the subroutine level, on the first call to a subroutine to read (or write) a line from a file, MTS will implicitly and automatically lock the file for reading (or modification) and then leave the file locked in that manner until the use of that file is complete. In general, the locking is associated with the FDUB (File or Device Usage Block) associated with the file, and the implicit and automatic unlocking is done when the FDUB is released.1At the command level, a FDUB is obtained for each use of a file by that command and the FDUB is not released until the (normal) termination of that command. At the subroutine level, FDUBs are obtained via subroutines such as GETFD and released via subroutines such as FREEFD.

If, while attempting to lock a file, MTS determines that according to the concurrent-use rules, it cannot lock the file as requested (for example, if another task has the file already locked for modification), MTS will implicitly and automatically attempt to queue the task to wait until the file can be locked. Before doing so, however, MTS will check to ensure that queuing the task to wait for the file will not result in a situation wherein the current task, as well as others, will be deadlocked indefinitely on their respective wait queues. If such is the case, MTS will not allow the task to wait but instead will return an error indication. An example of deadlocking is as follows:

(1) Suppose task A has file X locked for reading, and

---1When MTS implicitly locks a file through a particular FDUB, it may “raise” the locking class but will never “lower” it. Thus, if a user operating from the subroutine level first writes a line to a file and then reads a line from the same file, MTS will implicitly lock the file for modification before the first write and leave it locked for modification thereafter.

(2) Suppose task B has file Y locked for reading.

(3) Now suppose task A does something that requires file Y to be locked for modification.

MTS, realizing that someone else (task B) has file Y locked for reading, will queue task A to wait for the use of file Y to complete.

(4) Finally, suppose task B does something that requires file X to be locked for modification.

MTS realizes not only that someone else (task A) has file X locked for reading, but also that if task B is queued to wait for the use of file X to complete, neither task A nor task B will do another thing, since each would be waiting for the other (to unlock a file) before continuing. In this particular example, task B is not queued to wait, but instead an error indication is returned.

If the file is locked by another task, MTS normally will wait until the file is released by the other task. This waiting may be canceled by an attention interrupt, in which case the message

"FDname": wait to lock cancelled.

is printed.

It is anticipated that most shared-file use of MTS could be handled by the implicit automatic locking, unlocking, and waiting done by MTS. To be sure, however, there also needs to be some means ofexplicitlylocking and unlocking files, as well as some way of specifying a maximum time to wait on a file if such is desired. These facilities are necessary, for example, if a user operating at the command language level wished to empty a file and copy new information into it, all the while ensuring that after the file was empty and before the new information was copied in, no one would be able to read the (empty) file. Likewise, if a user is operating at the subroutine level, the facility would be necessary if one wished to read a line from a file, change it, and write the line back into the file, all the while ensuring that no other task could be attempting to read or modify that same line after it was read and before it was written back. Thus, MTS has available two commands (LOCK and UNLOCK) and two user-callable subroutines (LOCK and UNLK) to allow users toexplicitlylock and unlock files as well as to (optionally) request thatno waitingbe done, or that the wait is not to last longer than a certain amount of time if the locking cannot be accomplished. In addition, (batch) tasks can request that their tasks be terminated if for any reason their explicit locking requests cannot be satisfied.

Since,within any one task, the locking and unlocking of files is controlled by each use of the file (i.e., each FDUB), the question arises as to how a file is actually locked and unlocked within a task when more than one use (and thus more than one implicit or explicit locking request) is associated with the same file. In general, it can be said that a file is always locked at the level of the highest locking request associated with the file, and when a file is unlocked for a particular use, it is left locked at the highest remaining locking request associated with the file. Thus, for example, if the user explicitly LOCKs a file for reading (one use of the file) and then EMPTYs the file (a second use), MTS will implicitly and automatically lock the file for modification (the second use requires a higher locking class), empty the file, and then unlock the file for modification but leave it locked for reading (the highest remaining locking request). Likewise, if a user, operating at the subroutine level, has called GETFD twice for the same file and has implicitly locked the file for modification by writing the file via FDUB1 and then explicitly locked the file for read via FDUB2, the file would remain locked for modification (the highest level locking request). If then the user explicitly unlocked FDUB1, the file would be unlocked for modification but would remain locked for reading (the highest remaining locking request).

When a file is locked explicitly at the command level, it will remain locked until it is explicitly unlocked at the command level (or until the task signs off). Likewise, if a file is locked explicitly (or implicitly) at the subroutine level via a FDUB it will remain locked until:

(1) the file is explicitly unlocked via the same FDUB, (2) the FDUB is freed, or

(3) the program terminates execution normally (attention interrupts, program interrupts, calling the subroutines ERROR, MTS, or MTSCMD are notnormal terminations) or is unloaded.

In addition, EDITing a file implicitly locks the file as needed and leaves the file locked until a new file is edited or until the File Editor returns.

Furthermore, when a file is lockedexplicitly, either from command or subroutine level (assuming no other FDUB has a locking request associated with the file within the same task) the file will actually be locked as requested, i.e., the locking class will be either “raised” or “lowered” or left the same in order to conform to the actual request.

Finally, it should be noted that locking a file is in effect locking the name of that file. Thus, one can, for example,

LOCK FILE1 RENAME RENAME FILE1 AS FILE2 CREATE FILE1

all the while leaving FILE1 locked.

APPENDIX E

Dans le document The Michigan Terminal System (Page 156-160)