Related links

Ask the Wizard Questions

Language: Enqueue lock from DCL

The Question is:

I want to write a program to be called from DCL to enqueue a lock and
have the lock stay enqueued after the program exits. At a later point
in the DCL I want to call another program to dequeue the lock. How do
I get the lock to remain after the first program exits?

The Answer is:

If your process or the image has CMEXEC privilege, you can enqueue a
lock which will survive image rundown. To do this you need to execute
the call to SYS$ENQW in EXECUTIVE mode. If you wish the lock to be
visible beyond your immediate UIC group, you will also need SYSLCK
privilege and include the flag LCK$M_SYSTEM in the $ENQ.
To $DEQ the lock in a later image activation, you first need to
find the LKID using SYS$GETLKIW. This will also need to be done in
EXECUTIVE mode. The method I would suggest is to use a wildcard
search for a lock held by your PID and with the same resource name.
Beware - exceptions in EXECUTIVE mode will delete your process, and,
in some instances can crash your system. You also cannot reliably use
I/O from executive mode, nor can you use DEBUG. A rough outline of
the code required is:
To take out the lock:
...
$CMEXEC(EnqRoutine,0)
...
EnqRoutine
$ENQW(lkmode=LCK$K_mode,lksb=lksb,flags=LCK$M_SYSTEM,
resnam='your-resource-name',acmode=PSL$C_EXEC)
END EnqRoutine
To release the lock
Use $GETJPI to determine your own PID => Self
...
$CMEXEC(DeqRoutine,0)
...
DeqRoutine
init GETLKI item list to return LKI$_RESNAM, LKI$_PID and LKI$_LKID
LKSB=0 (wildcard)
REPEAT
status=$GETLKIW(lkidadr=LKSB,itmlst=itmlst,iosb=iosb)
UNTIL bad status OR ((PID=Self) AND (RESNAM='your-resource-name')
IF good status THEN $DEQ(lkid=LKID)
END DeqRoutine
Be careful with this stuff, as well as being privileged and difficult
to debug, it's very easy to deadlock yourself.