☜ | LOCKM[UMPS] by Example | ☞ |
Introduced in the 1977 ANSI M[UMPS] language standard.
Lock A,B,C
Unlock all, LOCK C
Well... actually, when anybody else has either A or B
locked, this sequence of commands would wait first for these to be
unlocked...
Lock (A,B,C)
Unlock all, LOCK A, B and C
Lock X:TIME
Unlock all, LOCK X with time-out of TIME
seconds.
Lock
Unlock all
If '$Data(^PATIENT(ID)) Do
. Lock +^PATIENT(ID):5
. ; create patient record
. Lock -^PATIENT(ID)
. Quit
Assume that two processes execute this program segment
simultaneously, and that the chronology of the actions between
the jobs is as follows:
One process | Other process |
---|---|
If '$Data(^PATIENT(123)) | |
- swap out - | |
If '$Data(^PATIENT(123)) | |
Do | |
Lock +^PATIENT(123) | |
; create patient record | |
Lock -^PATIENT(123) | |
- swap in - | |
Do | |
Lock +^PATIENT(123) | |
create patient record |
... Well, that’s what we just wanted to avoid by using the Lock command, wasn’t it...
Correct usage of the Lock command in this context would
be:
Lock +^PATIENT(ID):TIME
Else Write "Cannot create record."
Quit
Quit:$Data(^PATIENT(ID))
; create patient record
Lock -^PATIENT(ID)
Always Lock before a reference is made; that is the only
way to synchronize processes.
Added in the 1990 ANSI M[UMPS] language standard:
Lock +D
Add D to the LOCK list.
Lock -A
Remove A from the LOCK list.
Assume that
A="KLM(1)"
KLM(2,3,4)="PQR"
Lock @A@(3,4) would be equivalent to
Lock "PQR", which is an error, and
Lock @@A@(3,4) would be equivalent to Lock
PQR.
The ANSI standard behavior is defined as follows:
Lock (without a plus)
Lock with a plus
Lock with a minus
Hence, the behavior should be:
Lock +^GLO(1,2) | Adds one instance of the name ^GLO(1,2) to the lock table; may need to wait until another job relinquishes its lock on this name. |
Lock +^GLO(1,2,3) | Adds one instance of the name ^GLO(1,2,3) to the lock table; will always succeed immediately because the a name governing a superset is already owned. |
Lock -^GLO(1,2,3) | Removes one instance of the name ^GLO(1,2,3) from the lock table |
Lock +GLO(1) | Adds one instance of the name ^GLO(1) to the lock table; may need to wait, e.g. if someone else owns lock on ^GLO(1,5). |
Lock +GLO(2) | Adds one instance of the name ^GLO(2) to the lock table; may need to wait until another job relinquishes its lock on this name. |
Lock -^GLO | If there is an occurrence of ^GLO for the current job, one instance will be removed from the lock table, othewise no effect |
So, assuming that the lock table is empty, and the number of the current job is 1, the sequence of events will be:
Command | Name | Count | Owner |
---|---|---|---|
Lock +^GLO(1,2) | ^GLO(1,2) | 1 | 1 |
Command | Name | Count | Owner |
Lock +^GLO(1,2) | ^GLO(1,2) | 2 | 1 |
Command | Name | Count | Owner |
Lock +^GLO(1,2,3) | ^GLO(1,2) | 2 | 1 |
^GLO(1,2,3) | 1 | 1 | |
Command | Name | Count | Owner |
Lock -^GLO(1,2,3) | ^GLO(1,2) | 2 | 1 |
Command | Name | Count | Owner |
Lock +GLO(1) | ^GLO(1,2) | 2 | 1 |
^GLO(1) | 1 | 1 | |
Command | Name | Count | Owner |
Lock +GLO(2) | ^GLO(1,2) | 2 | 1 |
^GLO(2) | 1 | 1 | |
Command | Name | Count | Owner |
Lock -^GLO(1,2) | ^GLO(1,2) | 1 | 1 |
Command | Name | Count | Owner |
Lock -^GLO | ^GLO(1,2) | 1 | 1 |
Assuming that the lock table has the depicted initial content, and the number of the current job is 1, and assuming that job number 3 would relinquish the locks that are requested by job number 1, the sequence of events would be:
Name | Count | Owner | Comment | |
---|---|---|---|---|
^GLO | 1 | 3 | ||
^GLO(1,2) | 1 | 3 | ||
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock +^GLO(1,2) | ^GLO | 1 | 3 | |
^GLO(1,2) | 1 | 1 | Added after other job relinquishes its lock | |
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock +^GLO(1,2) | ^GLO | 1 | 3 | |
^GLO(1,2) | 2 | 1 | Count increases by 1 | |
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock +^GLO(1,2,3) | ^GLO | 1 | 3 | |
^GLO(1,2) | 2 | 1 | ||
^GLO(1,2,3) | 1 | 1 | Can always be added immediately | |
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock -^GLO(1,2,3) | ^GLO | 1 | 3 | |
^GLO(1,2) | 2 | 1 | ||
Entry is removed when count reaches zero | ||||
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock +GLO(1) | ^GLO | 1 | 3 | |
^GLO(1) | 1 | 1 | Can be added as long a no-one else owns it | |
^GLO(1,2) | 2 | 1 | ||
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock +GLO(2) | ^GLO | 1 | 3 | |
^GLO(1) | 1 | 1 | ||
^GLO(1,2) | 2 | 1 | ||
^GLO(2) | 1 | 1 | Can be added as long a no-one else owns it | |
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock -^GLO(1,2) | ^GLO | 1 | 3 | |
^GLO(1) | 1 | 1 | ||
^GLO(1,2) | 1 | 1 | Count decreases by 1 | |
^GLO(2) | 1 | 1 | ||
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 | ||
Command | Name | Count | Owner | Comment |
Lock -^GLO | ^GLO | 1 | 3 | Since the requesting job doesn’t own this entry, no change |
^GLO(1) | 1 | 1 | ||
^GLO(1,2) | 1 | 1 | ||
^GLO(2) | 1 | 1 | ||
^GLO(5) | 1 | 3 | ||
^GLO(7) | 1 | 3 |
Approved for addition in a future M[UMPS] language standard.
The option has been added to use "subscript indirection" in name references that occur in arguments of Lock commands.
Set Root="^DIC(19)"
Lock +@Root@(42,0)
is now equivalent with Lock +^DIC(19,42,0)
Examples with naked references:
Lock NAME
Set ^ABC(1,2)="reset naked indicator"
; naked indicator is now ^ABC(1,
Lock ^(3,4)
; Error occurs (invalid nref in LOCK argument)
; This is a general syntactical error; no M... error code has
been assigned.
; naked indicator is unchanged
Lock NAME
Set ^ABC(1,2)="reset naked indicator"
; naked indicator is now ^ABC(1,
Lock ^(3,^(4,5))
; fetch ^(4,5) = ^ABC(1,4,5)
; naked indicator is now ^ABC(1,4,
; Error occurs (invalid nref in LOCK argument)
; Note that the naked indicator may change while evaluating
subscripts,
; but not as a side-effect of the LOCK command itself.
Copyright © Standard Documents; 1977-2024 MUMPS Development Committee;
Copyright © Examples: 1995-2024 Ed de Moel;
Copyright © Annotations: 2003-2008 Jacquard Systems Research
Copyright © Annotations: 2008-2024 Ed de Moel.
The information in this page is
NOT authoritative and subject to be modified
at any moment.
Please consult the
appropriate (draft) language standard for an
authoritative definition.
Some specifications are "approved for inclusion in a future standard". Note that the MUMPS Development Committee cannot guarantee that such future standards will indeed be published.
This page most recently updated on 15-Nov-2023, 14:45:36.
For comments, contact Ed de Moel (demoel@jacquardsystems.com)