|
HP OpenVMS System Services Reference Manual
The following diagram shows the format of the lock status block and the
optional lock value block:
The following table defines the status block fields:
Status Block Field |
Definition |
Condition value
|
A word in which $ENQ writes a condition value describing the final
disposition of the lock request; for example, whether the lock was
granted, converted, and so on. The condition values returned in this
field are described in the Condition Values Returned in the Lock Status
Block section, which appears following the list of condition values
returned in R0.
|
Reserved
|
A word reserved by HP.
|
Lock identification
|
A longword containing the identification of the lock.
For a new lock, $ENQ writes the lock identification of the
requested lock into this longword when the lock request is queued.
For a lock conversion on an existing lock, you must supply the lock
identification of the existing lock in this field.
|
Lock value block
|
A user-defined structure containing information about the resource.
This information is interpreted only by the user program.
The length of the user data structure is 16 bytes if only the
LCK$M_VALBLK flag is specified. The user data structure is 64 bytes if
both the LCK$M_VALBLK and LCK$M_XVALBLK flags are specified. The length
of the system copy of the lock value block structure is always 64 bytes
on OpenVMS and I64 systems beginning with OpenVMS Version 8.2. Refer to
the OpenVMS Programming Concepts Manual for information about using the LCK$M_XVALBLK flag in
a mixed-version cluster.
When a process acquires a lock on a resource, the lock management
facility provides that process with a process-private copy of the lock
value block associated with the resource, provided that process has
specified the LCK$M_VALBLK flag in the
flags argument. The copy provided to the process is a
copy of the lock value block stored in the lock manager's database.
The copy of the lock value block maintained in the lock database is
either read into or updated from the caller's lock value block. The
method used depends on the lock mode of the lock that was granted, and
on the mode of the original lock held, if the operation was a
conversion.
In general, a grant or a conversion to an equal-level or
higher-level lock mode reads the lock value from the lock database into
the caller's lock value block.
When a lock conversion from EX-mode or PW-mode to an equal-level or
lower-level lock mode occurs, the contents of the caller's lock value
block are written into the lock database. The specific behavior of the
lock conversion is documented in the OpenVMS Programming Concepts Manual in the table
entitled, "Effect of Lock Conversion on Lock Value Block".
|
Callers of $ENQ are provided with copies of the updated lock value
block from the lock database in the following way: when $ENQ grants a
new lock to the caller or converts the caller's existing lock to the
same lock mode or a higher lock mode, $ENQ copies the lock value block
from the lock database to the caller's lock value block, provided the
caller has specified the LCK$M_VALBLK flag.
The Description section describes events that can cause the lock value
block to become invalid.
flags
OpenVMS usage: |
mask_longword |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by value |
Flags specifying options for the $ENQ operation. The
flags argument is a longword bit mask that is the
logical OR of each bit set, where each bit corresponds to an option.
The $LCKDEF macro defines a symbolic name for each flag bit. The
following table describes each flag:
Flag |
Description |
LCK$M_NOQUEUE
|
When this flag is specified, $ENQ does not queue the lock request
unless the lock can be granted immediately. By default, $ENQ always
queues the request.
If you specify LCK$M_NOQUEUE in a lock conversion operation and the
conversion cannot be granted immediately, the lock remains in the
original lock mode.
|
LCK$M_SYNCSTS
|
When you specify this flag, $ENQ returns the successful condition value
SS$_SYNCH in R0 if the lock request is granted immediately; in this
case, no completion asynchronous system trap (AST) is delivered and no
event flag is set. If the lock request is queued successfully but
cannot be granted immediately, $ENQ returns the condition value
SS$_NORMAL in R0; then when the request is granted, $ENQ sets the event
flag and queues an AST if the
astadr argument was specified.
|
LCK$M_SYSTEM
|
When you specify this flag, the resource name is interpreted as
systemwide. By default, resource names are qualified by the user
identification code (UIC) group number of the creating process. This
flag is ignored in lock conversions.
|
LCK$M_VALBLK
|
When you specify this flag, the lock status block contains a lock value
block. The initial value of the lock value block is zero (0). See the
description of the
lksb argument and the LCK$M_XVALBLK flag for more
information.
|
LCK$M_CONVERT
|
When you specify this flag, $ENQ performs a lock conversion. In this
case, the caller must supply (in the second longword of the lock status
block) the lock identification of the lock to be converted.
|
LCK$M_NODLCKWT
|
By specifying this flag, a process indicates to the lock management
services that it is not blocked from execution while waiting for the
lock request to complete. For example, a lock request might be left
outstanding on the waiting queue as a signaling device between
processes.
This flag helps to prevent false deadlocks by providing the lock
management services with additional information about the process
issuing the lock request. When you set this flag, the lock management
services do not consider this lock when trying to detect deadlock
conditions.
|
|
A process should specify the LCK$M_NODLCKWT flag only in a call to the
$ENQ system service. The $ENQW system service waits for the lock
request to be granted before returning to the caller; therefore,
specifying the LCK$M_NODLCKWT flag in a call to the $ENQW system
service defeats the purpose of the flag and can result in a genuine
deadlock being ignored.
The lock management services make use of the LCK$M_NODLCKWT flag
only when the lock specified by the call to $ENQ is in either the
waiting or the conversion queue.
Improper use of the LCK$M_NODLCKWT flag can result in the lock
management services ignoring genuine deadlocks.
|
LCK$M_NODLCKBLK
|
By specifying this flag, a process indicates to the lock management
services that, if this lock is blocking another lock request, the
process intends to give up this lock on demand. When you specify this
flag, the lock management services do not consider this lock as
blocking other locks when trying to detect deadlock conditions.
A process typically specifies the LCK$M_NODLCKBLK flag only when it
also specifies a blocking AST. Blocking ASTs notify processes with
granted locks that another process with an incompatible lock mode has
been queued to access the same resource. Use of blocking ASTs can cause
false deadlocks, because the lock management services detect a blocking
condition, even though a blocking AST has been specified; however, the
blocking condition will disappear as soon as the process holding the
lock executes, receives the blocking AST, and dequeues the lock.
Specifying the LCK$M_NODLCKBLK flag prevents this type of false
deadlock.
To enable blocking ASTs, the
blkast argument of the $ENQ system service must
contain the address of a blocking AST service routine. If the process
specifies the LCK$M_NODLCKBLK flag, the blocking AST service routine
should either dequeue the lock or convert it to a lower lock mode
without issuing any new lock requests. If the blocking AST routine does
otherwise, a genuine deadlock could be ignored.
The lock management services make use of the LCK$M_NODLCKBLK flag
only when the lock specified by the call to $ENQ has been granted.
Improper use of the LCK$M_NODLCKBLK flag can result in the lock
management services ignoring genuine deadlocks.
|
LCK$M_NOQUOTA
|
This flag is reserved by HP. When you set this flag, the calling
process is not charged Enqueue Limit (ENQLM) quota for this new lock.
The calling process must be running in executive or kernel mode to set
this flag. This flag is ignored for lock conversions.
|
LCK$M_CVTSYS
|
This flag is reserved by HP. When you set this flag, the lock is
converted from a process-owned lock to a system-owned lock. The calling
process must be running in executive or kernel mode to set this flag.
|
LCK$M_EXPEDITE
|
This flag is valid only for new lock requests. Specifying this flag
allows a request to be granted immediately, provided the requested mode
when granted would not block any currently queued requests in the
resource conversion and wait queues. Currently, this flag is valid only
for NLMODE requests. If this flag is specified for any other lock mode,
the request will fail and an error of SS$_UNSUPPORTED will be returned.
|
LCK$M_QUECVT
|
This flag is valid only for conversion operations. A conversion request
with the LCK$M_QUECVT flag set will be forced to wait behind any
already queued conversions.
The conversion request is granted immediately, if there are no
already queued conversions.
The QUECVT behavior is valid only for a subset of all possible
conversions. Table SYS-35 defines the legal set of conversion requests
for LCK$M_QUECVT. Illegal conversion requests are failed with
SS$_BADPARAM returned.
|
LCK$M_XVALBLK
|
This flag is valid only if it is used in conjunction with the
LCK$M_VALBLK flag. When you specify the LCK$M_XVALBLK flag, you must
provide a 64-byte lock value block at the end of the lock states block
specified in the
lksb argument. If you do not specify this flag, only
the first 16 bytes of the lock value block buffer specified as part of
the lock status block in the
lksb argument will be read or written.
If the value block is written without this flag, the value block
will be flagged so that a future reader who specifies the LCK$M_XVALBLK
flag in the $ENQ system service call will receive the warning status
SS$_XVALNOTVALID until a future writer writes to the value block
specifying this flag.
|
Table SYS-35 Legal QUECVT Conversions
Lock Mode |
Lock Mode to Which Lock Is Converted |
at Which Lock Is Held |
NL |
CR |
CW |
PR |
PW |
EX |
NL
|
No
|
Yes
|
Yes
|
Yes
|
Yes
|
Yes
|
CR
|
No
|
No
|
Yes
|
Yes
|
Yes
|
Yes
|
CW
|
No
|
No
|
No
|
Yes
|
Yes
|
Yes
|
PR
|
No
|
No
|
Yes
|
No
|
Yes
|
Yes
|
PW
|
No
|
No
|
No
|
No
|
No
|
Yes
|
EX
|
No
|
No
|
No
|
No
|
No
|
No
|
Key to Lock Modes
NL---Null lock
CR---Concurrent read
CW---Concurrent write
PR---Protected read
PW---Protected write
EX---Exclusive lock
resnam
OpenVMS usage: |
char_string |
type: |
character-coded text string |
access: |
read only |
mechanism: |
by 32- or 64-bit descriptor--fixed-length string descriptor
(Alpha and I64) |
mechanism: |
by 32-bit descriptor--fixed-length string descriptor
(VAX) |
Name of the resource to be locked by this lock. The
resnam argument is the 32- or 64-bit address (on Alpha
and I64 systems) or the 32-bit address (on VAX systems) of a character
string descriptor pointing to this name. The name string can be from 1
to 31 bytes in length.
If you are creating a new lock, the resnam argument
should be specified because the default value for the
resnam argument produces an error when it is used to
create a lock. The resnam argument is ignored for lock
conversions.
parid
OpenVMS usage: |
lock_id |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by value |
Lock identification of the parent lock. The parid
argument is a longword containing this identification value.
If you do not specify this argument or specify it as 0, $ENQ assumes
that the lock does not have a parent lock. This argument is optional
for new locks and is ignored for lock conversions.
astadr
OpenVMS usage: |
ast_procedure |
type: |
procedure value |
access: |
call without stack unwinding |
mechanism: |
by 32- or 64-bit reference (Alpha and I64) |
mechanism: |
by 32-bit reference (VAX) |
AST service routine to be executed when the lock is either granted or
converted. The astadr argument is the 32- or 64-bit
address (on Alpha and I64 systems) or the 32-bit address (on VAX
systems) of this routine. The AST is also delivered when the lock or
conversion request is canceled. Cancellation occurs if you use $DEQ
with the cancel modifier or if the waiting request is chosen to break a
deadlock.
If you specify the astadr argument, the AST routine
executes at the same access mode as the caller of $ENQ.
astprm
OpenVMS usage: |
user_arg |
type: |
quadword (unsigned) |
access: |
read only |
mechanism: |
by value |
AST parameter to be passed to the AST routine specified by the
astadr argument. The astprm argument
specifies this quadword parameter.
blkast
OpenVMS usage: |
ast_procedure |
type: |
procedure value |
access: |
call without stack unwinding |
mechanism: |
by 32- or 64-bit reference (Alpha and I64) |
mechanism: |
by 32-bit reference (VAX) |
Blocking AST routine to be called whenever this lock is granted and is
blocking any other lock requests. The blkast argument
is the 32- or 64-bit address (on Alpha and I64 systems) or the 32-bit
address (on VAX systems) of this routine. Locks that are converting to
a new mode, but that are not yet granted in the new mode, do not
receive blocking ASTs.
You can pass a parameter to this routine by using the
astprm argument.
acmode
OpenVMS usage: |
access_mode |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by value |
Access mode to be associated with the resource name. The
acmode argument indicates the least privileged access
mode from which locks can be queued on the resource.
This argument does not affect the access mode associated with the lock
or its blocking and completion ASTs. The acmode
argument is a longword containing the access mode. The $PSLDEF macro
defines the following symbols for the four access modes:
Symbol |
Access Mode |
PSL$C_KERNEL
|
Kernel
|
PSL$C_EXEC
|
Executive
|
PSL$C_SUPER
|
Supervisor
|
PSL$C_USER
|
User
|
The $ENQ service associates an access mode with the lock in the
following way:
- If you specified a parent lock (with the parid
argument), $ENQ uses the access mode associated with the parent lock
and ignores both the acmode argument and the caller's
access mode.
- If the lock has no parent lock (you did not specify the
parid argument or specified it as 0), $ENQ uses the
least privileged of the caller's access mode and the access mode
specified by the acmode argument. If you do not
specify the acmode argument, $ENQ uses the caller's
access mode.
rsdm_id
OpenVMS usage: |
longword |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by value |
Resource domain identification. The rsdm_id argument
is a longword specifying the resource domain association through which
a new lock is to be taken. This argument is ignored for lock
conversions and sublocks (parid is nonzero). Valid
resource domain identifiers are returned from the $SET_RESOURCE_DOMAIN
service, or by the constants RSDM$K_SYSTEM_RSDM_ID or
RSDM$K_PROCESS_RSDM_ID, which are defined by the $RSDMDEF macro in
STARLET.
nullarg
OpenVMS usage: |
null_arg |
type: |
longword (unsigned) |
access: |
read only |
mechanism: |
by value |
Placeholding argument reserved by HP.
Description
The Enqueue Lock Request service queues a new lock or lock conversion
on a resource. The $ENQ service completes asynchronously; that is, it
returns to the caller after queuing the lock request without waiting
for the lock to be either granted or converted. For synchronous
completion, use the Enqueue Lock Request and Wait ($ENQW) service. The
$ENQW service is identical to the $ENQ service in every way except that
$ENQW returns to the caller when the lock is either granted or
converted.
The $ENQ service uses system dynamic memory for the creation of the
lock and resource blocks.
When $ENQ queues a lock request, it returns the status of the request
in R0 and writes the lock identification of the lock in the lock status
block. Then, when the lock request is granted, $ENQ writes the final
completion status in the lock status block, sets the event flag, and
calls the AST routine if this has been requested.
When $ENQW queues a lock request, it returns status in R0 and in the
lock status block when the lock has been either granted or converted.
Where applicable, it simultaneously sets the event flag and calls the
AST routine.
Invalidation of the Lock Value Block
In some situations, the lock value block can become invalid. In these
situations, $ENQ warns the caller by returning the condition value
SS$_VALNOTVALID in the lock status block, provided the caller has
specified the flag LCK$M_VALBLK in the flags argument.
The SS$_VALNOTVALID condition value is a warning message, not an error
message; therefore, the $ENQ service grants the requested lock and
returns this warning on all subsequent calls to $ENQ until either a new
lock value block is written to the lock database or the resource is
deleted. Resource deletion occurs when no locks are associated with the
resource.
The following events can cause the lock value block to become invalid:
- If any process holding a protected write or exclusive mode lock on
a resource is terminated abnormally or exits before explicitly
dequeuing the lock or converting it to a lover-level lock mode, the
lock value block becomes invalid.
- If a process holding a protected write or exclusive mode lock on
the resource calls the Dequeue Lock Request ($DEQ) service to dequeue
this lock and specifies the flag LCK$M_INVVALBLK in the
flags argument, the lock value block maintained in the
lock database is marked invalid.
- If a node in an OpenVMS Cluster system fails, and a process on that
node was holding or might have been holding a protected write or
exclusive mode lock on the resource, the lock value block becomes
invalid.
This situation is dependant on which cluster node is the
master node for the resource. The following describes the two ways in
which this situation can arise:
- If a node was holding a protected write or exclusive mode lock on
the resource:
If the node that failed was not the master of the
resource tree, the master node will know what locks were held by the
node that failed. These locks will be removed from the resource and if
a removed lock was for protected write or exclusive mode, the lock
value block becomes in valid.
- If a node might have been holding a protected write or exclusive
mode lock on the resource:
If the node that failed was the master
of the resource, a remaining node in the cluster will become the new
master. If the new master finds that all granted locks on the resource
were for null mode locks or for concurrent read locks, or for both,
then the new master does not know if the failed node held a protected
write or exclusive mode lock. The lock value block will be set to
invalid in this case. If the resource has any granted lock with a
mode other than null mode or concurrent read, then the failed node
could not have held a protected write or exclusive mode lock, and the
lock value block will not be marked as invalid.
Invalidation of the Extended Lock Value Block
The extended lock value block can be marked invalid in the following
situations:
- If a program updates the lock block specifying only LCK$M_VALBLK
without LCK$M_XVALBLK, only the first 16 bytes of the lock value block
will be written. The remaining 48 bytes will not be modified. A reader
who, in the future, specifies the LCK$M_XVALBLK flag in the $ENQ system
service call will be be given all 64 bytes but will receive the warning
status SS$_XVALNOTVALID flag.
- In a cluster with VAX nodes or nodes using versions of OpenVMS
prior to Version 8.2, if a program running on one of the VAX or older
version nodes writes to the value block, only the first 16 bytes of the
lock value block will be written. As long as the resource is mastered
on a newer Alpha or I64 system, the remaining 48 bytes will not be
modified. A reader who, in the future, writes to the value block
specifying the LCK$M_XVALBLK flag in the $ENQ system service call will
be given all 64 bytes but will receive the warning status
SS$_XVALNOTVALID flag until a writer writes to the value block
specifying the LCK$M_XVALBLK flag.
- The last 48 bytes value block will be lost if a resource is
mastered on or remastered to a VAX or older-version node. In this case,
a reader who specifies the LCK$XVALBLK flag in the $ENQ system service
call will be given the first 16 bytes followed by 48 bytes of zeroes
and will receive the warning status SS$_XVALNOTVALID until a writer
writes to the value block specifying the LCK$M_XVALBLK flag.
In all of these cases, if the entire lock status block is invalid as
described in Invalidation of the Lock Value Block, the SS$_VALNOTVALID status will be
returned, overriding the SS$_XVALNOTVALID status.
Required Access or Privileges
To queue a lock on a systemwide resource, the calling process must
either have SYSLCK privilege or be executing in executive or kernel
mode.
To specify a parent lock when queuing a lock, the access mode of the
caller must be equal to, or less privileged than, the access mode
associated with the parent lock.
To queue a lock conversion, the access mode associated with the lock
being converted must be equal to, or less privileged than, the access
mode of the calling process.
Required Quota
- Enqueue limit (ENQLM) quota
- AST limit (ASTLM) quota in lock conversion requests that you
specify either the astadr or blkast
argument
Related Services
$DEQ, $ENQW, $GETLKI, $GETLKIW, $SET_RESOURCE_DOMAIN
Condition Values Returned
SS$_NORMAL
|
The service completed successfully; the lock request was successfully
queued.
|
SS$_SYNCH
|
The service completed successfully; the LCK$M_SYNCSTS flag in the
flags argument was specified, and $ENQ was able to
grant the lock request immediately.
|
SS$_ACCVIO
|
The lock status block or the resource name cannot be read.
|
SS$_BADPARAM
|
You specified an invalid lock mode in the
lkmode argument.
|
SS$_CVTUNGRANT
|
You attempted a lock conversion on a lock that is not currently granted.
|
SS$_EXDEPTH
|
The limit of levels of sublocks has been exceeded.
|
SS$_EXENQLM
|
The process has exceeded its enqueue limit (ENQLM) quota.
|
SS$_INSFMEM
|
The system dynamic memory is insufficient for creating the necessary
data structures.
|
SS$_IVBUFLEN
|
The length of the resource name was either 0 or greater than 31.
|
SS$_IVLOCKID
|
You specified an invalid or nonexistent lock identification, or the
lock identified by the lock identification has an associated access
mode that is more privileged than the caller's, or the access mode of
the parent was less privileged than that of the caller.
|
SS$_NOLOCKID
|
No lock identification was available for the lock request.
|
SS$_NOSYSLCK
|
The LCK$M_SYSTEM flag in the
flags argument was specified, but the caller lacks the
necessary SYSLCK privilege.
|
SS$_NOTQUEUED
|
The lock request was not queued; the LCK$M_NOQUEUE flag in the
flags argument was specified, and $ENQ was not able to
grant the lock request immediately.
|
SS$_PARNOTGRANT
|
The parent lock specified in the
parid argument was not granted.
|
Condition Values Returned in the Lock Status Block
SS$_NORMAL
|
The service completed successfully; the lock was successfully granted
or converted.
|
SS$_ABORT
|
The lock was dequeued (by the $DEQ service) before $ENQ could grant the
lock.
|
SS$_CANCEL
|
The lock conversion request has been canceled and the lock has been
regranted at its previous lock mode. This condition value is returned
when $ENQ queues a lock conversion request, the request has not been
granted yet (it is in the conversion queue), and, in the interim, the
$DEQ service is called (with the LCK$M_CANCEL flag specified) to cancel
this lock conversion request. If the lock is granted before $DEQ can
cancel the conversion request, the call to $DEQ returns the condition
value SS$_CANCELGRANT, and the call to $ENQ returns SS$_NORMAL.
|
SS$_DEADLOCK
|
A deadlock was detected.
|
SS$_ILLRSDM
|
The operation attempted is not allowed on the resource. Use SHOW
SECURITY to verify the access allowed to the specified resource domain.
|
SS$_NODOMAIN
|
The RSDM_ID argument passed to the $ENQ call either does not correspond
to a valid resource domain for your process, or the system is not
running the audit server process.
|
SS$_VALNOTVALID
|
The lock value block is marked invalid. This warning message is
returned only if the caller has specified the flag LCK$M_VALBLK in the
flags argument. Note that the lock has been
successfully granted despite the return of this warning message. Refer
to the Description section for a complete discussion of lock value
block invalidation.
|
SS$_XVALNOTVALID
|
The extended value block has been marked invalid because the previous
writer has written the value block without specifying the LCK$M_XVALBLK
flag. This warning message is returned only if the caller has specified
the LCK$M_XVALBLK flag in the
flags argument. Note that the lock is successfully
granted despite the return of this warning message.
Refer to the section Invalidation of the Extended Lock Value Block for a detailed discussion of
extended lock value block invalidation.
|
|