Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

In a network environment, an MFS should expect to receive calls that involve record and file locks. As with other aspects of the system, however, an MFS programmer must understand the underlying technology of locking in order to take full advantage of this group of calls.

Lock Semaphores

In order to remain compatible with the variety of networks supported in OpenInsight, the system uses a standard protocol for the establishment of locks. This is based on lock semaphores.

When an BASIC+ LOCK statement is executed, the system uses the file handle and record key information (if locking a record) to create a lock semaphore. In order to accommodate all potential network locking schemes, the semaphore is simplified by hashing the file and record information into a reduced eight-byte format.

Local Lock Table

The resulting semaphore is then stored in a lock table local to the workstation. This is done for several reasons.

  • First, OpenInsight supports the capability for programmers to attempt multiple locks on the same record. In trapping these locks locally, the system reduces lock overhead by avoiding extra lock calls made to the network. If a record is already locked by the local station, this can be detected without an additional call to the network.

  • Second, storing locks locally gives OpenInsight the ability to report that a lock has already been set by that station. (This is done by testing STATUS( ) after a lock has failed.) Some networks do not permit a station to lock the same record twice, and do not report back the proper error condition.

  • Finally, the hashing scheme OpenInsight uses to create the semaphores allows the possibility that entirely different file and record combinations can produce the same semaphore. By maintaining a local lock table, OpenInsight can detect this and arbitrate conflicts arising from duplicate semaphores.

Only non-duplicated semaphores are passed through to the filing system.

A lock is thus processed at two levels. The first is within the system before a call is made to the filing system. Only after the internal lock table has been examined -- and only if necessary -- is the lock call passed through to the MFS.

As a result, not all lock calls can be trapped at the MFS level.  For example, if a station has a record locked, and attempts to lock it again from a different program or level of execution, the MFS will never receive a lock call. Instead, the system will have already detected a conflict based on the local lock table, and will have returned the proper response to BASIC+.

The same is true of unlock calls. If the system can resolve an unlock call by referencing only the local lock table, it will do so. In these cases, as with the lock calls, the MFS will never receive the unlock call.

If the lock or unlock call does pass through to the MFS and down to the BFS, the filing system will return information about the lock and its status.

Info
Lock information returned by the BFS should never be altered by an MFS, as it will be stored in the local lock table, and be used to coordinate with other locks.

Locking Within An MFS

An MFS may require record locking as part of its own processing.  This will be the case, for instance, if an MFS such as an audit trail MFS must update files. As with any program, if executing in a network environment, the MFS should preserve file integrity by locking all records that are to be updated.

If an MFS must lock records, it should never do so with direct calls to the filing system. Instead, the MFS should execute BASIC+ LOCK calls. Moreover, when executing the BASIC+ LOCK calls, the MFS should always first fetch a proper file handle using a BASIC+ OPEN statement.

(Note that this is in contrast to the method used to access data in the file -- see the topic "Access to a File from Within an MFS" earlier in this chapter. Access to the same file should not be done via BASIC+ statements, whereas locking always must be done via BASIC+ OPEN and LOCK.)

By executing an BASIC+ LOCK statement, the local lock table will be updated properly.   A direct call to the filing system will not pass through the BASIC+ interpreter, and the local lock table will not be aware of locks made in this way; coordination with locally-held semaphores will not be possible.

In order to pass the proper file handle to the LOCK statement, the MFS should first fetch the handle using an BASIC+ OPEN statement. Though it might seem possible to use the HANDLE argument if locking files in the current file, the HANDLE argument does not contain the same handle information as returned by an BASIC+ OPEN statement. Since application programs use the full BASIC+ OPEN file handle when locking, an MFS should do so as well in order to guarantee coordination with these higher-level processes.

UNLOCK ALL Within An MFS

The UNLOCK.ALL call functions differently than other lock calls.  When an BASIC+ UNLOCK ALL statement is executed, the system does not pass individual lock calls to each open file.  Instead, the system reviews the list of installed filing systems and makes a single UNLOCK.ALL call to each filing system.

Because this call is directed to the filing system specifically, an MFS receiving an UNLOCK.ALL call does not need to pass the call along to subsequent filing systems. If a call is attempted to the next MFS, a load error will occur.

The system will call all MFSs that have been installed during the current session, even if no files using that MFS are currently attached.

The MFS should simply perform any tasks required to clear all pending locks for that filing system. When this task is complete, the MFS should return with status set to true.

Additional Lock Calls

Additional lock calls exist in the system that are not available to MFS programmers. These are calls that the system uses to initialize and reset itself; as a result, these calls are passed only via direct calls at system initialization and reset time.

System lock calls are:

  • LOCK.SEMAPHORE

  • UNLOCK.SEMAPHORE

  • SET.USER.SEMAPHORE

An MFS will never receive these calls, and should therefore simply execute a RETURN for the CODE values of 23, 24, and 25.