Updated August 2020; see History
(1) xcall XLOCK, mode, lock1, lock2 {,class}
(2) xcall XLOCK, mode, myjob, lock'array(1)
XLOCK provides an abstract symbolic scheme for locking anything, based on a pair of numeric values to which you assign your own meaning. Note that syntax two is used only for retrieving a list of locks (mode = 3).
Parameters
mode (Num) [in/out]
determines the operation, per the following table:
Value |
Description |
---|---|
0 |
Set lock specified by lock1 and lock2. If successful, mode is set to 0. Otherwise (if a conflicting lock exists), mode is set to the job number of the job holding the conflicting lock. See note about SBR=MXLOCK below for information how what happens if your job has already set the lock. |
1 |
Same as mode 0, except that if the lock cannot immediately be set, it waits until it can. |
2 |
Clear lock. On return, mode is set to 0 if your job did not own the lock (i.e. it was not cleared), else it is set to the number of locks cleared (which could be more than 1 in the case of wildcards). |
3 |
List locks. In this case, mode returns with the number of locks in the list; myjob is set to your job number, and lock'array contains the list of locks. |
4 |
Same as mode 0 but does not actually set the lock. |
5 |
Same as mode 1 but does not actually set the lock. |
6 |
Check for lock without wait; equivalent to mode 0 but without setting the lock. Similar to 4—when the class parameter is non-zero—but without any conflict/confusion with the reservations. |
7 |
Expanded list; equivalent to mode 3 but the returned lock'array elements also contain the lock class. See lokclass in lock'array below. |
lock# (B,2 or B,4) [in]
lock1 and lock2 together contain a pair of numbers which are being locked or released. The numbers themselves have no inherent meaning, but a typical use is for one to indicate a file channel number and the other a record number. A value of zero in either parameter acts as a wildcard. For example, the pair 22,0 matches all of the pairs whose first value is 22. (This might be useful for representing an exclusive lock on all records within file 22.) The double wildcard 0,0 matches all possible combinations. The range of values depends on whether the parameters are mapped as b,2 or b,4.
class (Num, 0-65535) [in]
Optional lock pool identifier. May be used to avoid potential conflicts between applications that might otherwise be using the same range of lock values. See Comments, below.
lock'array
map1 lock'array
map2 lok'jobnum,b,2
map2 lok1,b,x ! b,2 or b,4; must match size of mode param
map2 lok2,b,x ! " " "
map2 lokclass,b,2 ! always 2 bytes
Comments
The A-Shell implementation of XLOCK is upward compatible with the AMOS one, so you can refer to the AlphaBASIC documentation for more details. Note the following A-Shell enhancements:
• | A-Shell supports lock1 and lock2 variables of either B,2 or B,4 (allowing values of up to two billion), whereas the AMOS version is limited to two-byte values. |
• | Under A-Shell, you have the option of treating a value previously locked by your job as available (default) or locked. In the latter case, you must set the miame.ini setting SBR=MXLOCK; see the system parameters MXLOCK and AXLOCK, the latter of which controls whether a certain bug in the AMOS implementation will be emulated or not.) |
• | The optional class parameter allows you to create multiple locking pools (such as in multiple applications) which do not conflict with each other. The standard version of XLOCK uses lock class 0 for normal locks and lock class 256 for pending exclusive locks. Lock class 1 is used by the Aesops routine LOCK.SBR, and classes 2 and 3 are used by the OmniLedger routines XFLOCK.SBR and XLOCKS.SBR, respectively. If you want to define your own, we suggest picking something in the range of 100 to 200. |
• | An additional enhancement is that of lock "reservations." These were implemented to reduce the difficulty of establishing an exclusive (or wildcard) lock on a file (or other resource, represented by the lock1 value) in which multiple jobs are actively placing individual record locks. The problem is that the job desiring the exclusive lock may have to wait an unreasonable amount of time, since as long as there is one lock in the lock1 resource, the exclusive lock cannot be set, and even worse, there is no way to stop additional jobs from coming along and setting locks. The idea of the lock "reservation" is that once set, no new locks can be set on the resource, except by jobs that already have one or more locks set on that resource. This allows those jobs already using the resource to finish their transaction, but any additional jobs will have to wait until after the exclusive lock activity is complete. To use this feature, set mode to 4, lock1 to the resource you want exclusive control of, and lock2 to zero. This acts just like mode 0 (lock but do not wait) except that if the exclusive (wildcard) lock cannot be established, a reservation is set instead (using lock class 256). The calling job gets the same failure code as it would for mode 0 (i.e. mode is set to the job number owning the first conflicting lock). However, from that point on, no other jobs can set a lock conflicting with the reservation, unless they already have a lock set in that range. The calling job then repeats the mode 4 request periodically until the return value indicates success (at which point the reservation will have been converted to a normal lock, or in other words, the lock class will be changed from 256 back to 0). |
• | The final enhancement is the addition of two new modes which allow you to check for the presence of a lock without actually having to place one. mode 4 is like mode 0 (no waiting), and mode 5 is like mode 1 (wait until available) except that modes 4 and 5 do not actually set a lock. It will be left as an exercise for the clever programmer to figure out what possible motivation there could be for such a capability. |
• | The QUTL utility may be used to display the list of locks in use, as well as to forcefully clear them by resetting the job owning the locks. |
• | Note that XLOCK isn't really a file or record locking system, even though that's what people mostly use it for. It is really just a mechanism for limiting access to arbitrary resources which are coded using a pair of numeric values. There is no inherent meaning to the numeric values contained in your "locks". It is the application—and not A-Shell or the operating system—that has assigned meaning to the numeric values, typically using the first number to indicate the file channel and the second to indicate the record number. |
• | Modes 3 and 7 pick up the array size from the parameter passed, whether it is passed as an unformatted block, or as the first element of the array. The value returned in mode (number of locks set) will be the total number of locks set (as before), but the list will be limited to the size of the array. Previously it may have overrun the array if it was not large enough to hold all the locks. |
History
2020 August, A-Shell 6.5.1688: If an out-of-queue blocks condition, or other queue system failure occurs while trying to place an XLOCK, it now returns a non-zero value in the MODE parameter, and also displays a messagebox clarifying the problem, with abort/retry/ignore options. Previously it merely displayed "?Out of queue blocks" but did not return an error code, so the application had no way of recognizing the problem. Note that the issue didn't affect FLOCK, which does return status 103 for these queue error conditions.
2019 December, A-Shell 6.5.1672: Add mode values 6 and 7.