Generate lock
A task wishing to use a lock must first generate it. This is performed implicitly by calling the LKENQ macro. The lock is generated by the DLM. When a new lock that does not yet exist is generated, both parts of the lock, namely the user-dependent and the user-independent parts, are generated. If the lock to be generated already exists, only the user-dependent part of the lock is generated and concatenated with the user-independent part.
Lock ID (LOCKID)
After a lock is generated, the task is given a (task-specific) lock ID (LOCKID) (LKENQ macro, LOCKID operand). The lock ID must be specified by the calling task if other calls referring to the same lock are made to the DLM. Other tasks that use the same lock and thus the same lock name have different lock IDs for that lock.The lock ID becomes invalid when the calling program releases it (LKDEQ macro) or when the program is terminated. A value equal to 0 is never supplied by the DLM as a lock ID.
To avoid incompatible lock requests, a new lock request must always be generated with LCKMODE = *NU (LKENQ macro) so that it can be allocated immediately (GRANTED status). Otherwise the lock request receives the WAITING status which it retains until all lock requests with the status GRANTED and CONVERTING have been released before it can be allocated. When the lock request has been allocated the lock mode can be converted with the LKCVT macro, whereupon the request switches between the GRANTED and the CONVERTING statuses only (see "Structure of a DLM lock").Lock request conversion
An existing and already allocated lock belonging to a user can be converted from one lock mode to another (LKCVT macro). The LKCVT requests are executed before a new lock request (LKENQ macro), apart from lock requests in NU mode, is executed.
During the conversion of the lock mode, the lock remains allocated in the original lock mode. The lock request receives the CONVERTING status. If the lock request can be allocated, then it is assigned the GRANTED status.The lock mode has now been converted.
Relationship between lock modes
Lock mode1
Lock mode 2
NU
CR
CW
PR
PW
EX
NU
e
h
h
h
h
h
CR
l
e
h
h
h
h
CW
l
l
e
h
h
h
PR
l
l
h
e
h
h
PW
l
l
l
l
e
h
EX
l
l
l
l
l
e
e
Lock mode 2 is equal to lock mode 1
l
Lock mode 2 is weaker than lock mode 1
h
Lock mode 2 is stronger than lock mode 1
Releasing a lock
A lock can be released in two ways:
Firstly, the lock can be released by the calling task (LKDEQ macro). This means that the caller's allocated lock request is canceled and the lock ID (LOCKID) is invalidated. Further use of the invalid lock ID leads to error codes, particularly if the lock still exists.The user-dependent part of the lock, and all its user-specific information which has been stored together with the lock, are deleted from the DLM data structure. If the user is the last (only) user of this lock, the user-independent part of the lock is also deleted. In this way the lock itself is deleted from the DLM data structure.
Secondly, a task's existing lock request can be converted to a weaker lock mode (see table on "Structure of a DLM lock"). The lock ID (LOCKID) remains valid and can continue to be used (LKCVT macro).
Canceling a lock request
Lock requests which have not yet been allocated by the DLM can be canceled with the LKCAN macro.
Lock requests which have been generated by the LKENQ macro and have the status WAITING or CONVERTING are completely canceled. If the lock request has the status GRANTED, i.e. if the lock is already allocated, processing is terminated with an error code. This lock request must be released with the LKDEQ macro.
Lock requests which are to be converted with the LKCVT macro and have the status CONVERTING are not canceled. Only the conversion job is canceled.
The call can be synchronous or asynchronous.
Outputting information on locks
The LKINF macro provides information on which locks are already being used. Several search filters can be activated to narrow the selection. The locks are identified by their lock names. The lock names may be fully or partially qualified names. If partially qualified lock names are specified, the access operation can take a very long time as the entire DLM database has to be searched for hits. This depends on the size of the DLM database.
Timeout detection
The user can specify a wait time and a hold time for the lock request, which is checked by the DLM. If the lock request cannot be allocated during the wait time, it is terminated with an error code or a wait time timeout is generated.
If the hold time exceeds the time limit, the lock holder is informed by the release event. If a hold time is specified, a release event (RELEVTT) must also be specified.
If the value 0 was entered as the time limit for the lock request, this lock request is identified as an immediate request. Immediate requests which cannot be allocated are terminated with the return code X'00828006'.
Lock Status Block
The Lock Status Block (LSB) is part of the user address space and has two main tasks.
Firstly, the LSB is needed for all asynchronous DLM calls. The LSB is the communication area between the DLM and the calling program. The asynchronous allocation of the lock is notified to the user by the appropriate return code being set in the LSB. The user is informed of the specified event method.
The LSB must be initialized before asynchronous functions can be requested by the DLM. This is done by calling the LKLSB macro with MF=L. The initialization values are written in the LSV area. The DLM can now decide whether or not the transferred address indicates a valid LSB. If the lock is allocated, the LSB must be available for the DLM, otherwise no data is transferred. The error is reported to the calling program using the event method.
Secondly, the LSB is needed if the Lock Value Block is to be read or written, irrespective of whether the requests are synchronous or asynchronous.
The lock value which the user wishes to write or which is supplied to the user during a read request is located in the Lock Status Block. The address of the LSB is specified in the operand list of the current DLM call (LSBADR operand in the macros LKENQ, LKCVT, LKDEQ and LKCAN).
Status information
The DLM keeps status information about the release of the last lock in PW or EX mode. The release was executed normally if the lock was released by the lock holder (LKDEQ macro). The status information is set to VALID.
If the release was terminated abnormally, the status information is set to INVALID. The release is terminated abnormally if the program, the task, or the node on which the lock holder is located was terminated before the lock was released.
The status information provides information about the validity of the Lock Value Block, which is handled in the same way. The handling of the status information is not necessarily linked to the handling of the Lock Value Block
The status information is sent to every subsequent lock holder until the status information has been reset to VALID. If the requested lock mode was NU or CR the information may no longer be current.
The status information INVALID can be reset to VALID if another lock holder requests the lock in PW or EX mode, is allocated it, and, when it is released, specifies that the status is to be reset. This can take place irrespective of the Lock Value Block. However, it is possible to change the Lock Value Block and reset the status to VALID with a DLM call.
Termination sequence of lock requests during termination of the lock holder process
During abnormal termination of a lock holder process (task or program), the lock requests are released in a defined sequence.
The caller can specify the release time for his lock in one of the following three classes during generation of a lock request (TERMNTE operand in the LKENQ macro):
FIRST
This class contains locks which are released before or at the same time
as the locks in the next class, SECOND.SECOND
This class contains locks which are released after or at the same time as
the locks in the previous class, FIRST, and before or at the same time as
the locks in the next class, THIRDTHIRD
This class contains locks which are released after or at the same time as
the locks in the previous class, SECOND.To ensure that all locks from different processes which belong to the same application are handled in the same way, the caller must ensure that all LKENQ requests are called with the same operands.This is not checked by the DLM during the LKENQ call.