In the function below, I am using the Windows LockFile API.
Caclulating which byte to lock comes from other logic, and the numbers can
be large. I am getting a "range check error" on assignment.
Yet, as I understand it, a DWORD is:
Longword 0..4294967295 unsigned 32-bit
The value which throws the exception is 429,496,5455
This is less than the documented max of 429,496,7295
Any ideas on how to debug greatly appreciated, thank you.
==============================================================
const
{
Row/Slot numbers are 0-origin
Station/Task numbers are 1-origin
A resource name determines a row/slot.
1st byte in region is "held exclusive"
Remainder of region has 1 byte for every Station/Task.
}
EZMAXROW = 19; // EZSEMTAB data area
EZPAGESIZE = 512; // EZSEMTAB data block
EZBASE = EZMAXROW * EZPAGESIZE;
EZRSCSIZE = 10;
EZMAXTASK = 16;
EZMAXSTATION= 512;
EZMAXSLOT = 51;
EZSLOTSIZE = 1+(EZMAXTASK * EZMAXSTATION); // Exclusive + one for
everybody
EZROWSIZE = (EZMAXSLOT * EZSLOTSIZE);
...........
function TIMSPlusTask.Exclusive(rsc:string; const
Table:TDataSet=nil):Boolean;
var
lower,upper:DWORD;
begin
...
Result:=False;
while not Result do
begin
EZSEMTAB.Mutex := TRUE;
// An exclusive lock requires a shared lock
if not FLockList.Shared[iRow,iSlot] then
begin
if not EZSEMTAB.isLocked(iRegion,1) then
EZSEMTAB.Lock(iByte) // Got shared access
else
begin
// Can't get shared
EZSEMTAB.Mutex := False;
if RetryDialog then continue else break;
end;
end;
{ Are we now the only ones holding this resource?
We should be able to lock either sides of this slot:
everything outside our own task byte.
iRegion < iByte <= (iRegion+EZSLOTSIZE-1)
If yes, we may lock the iRegion EXCLUSIVE byte now.
}
lower := iByte - iRegion;
upper := iRegion + (EZSLOTSIZE-1) - iByte; ******* RANGE CHECK ERROR
HERE *******
if (EZSEMTAB.isLocked(iRegion,lower)) or
(EZSEMTAB.isLocked(iByte+1,upper)) then
begin
EZSEMTAB.Mutex:=False;
EZSEMTAB.UnLock(iByte);
if RetryDialog then continue else break;
end else
begin
// Gotcha exclusive
EZSEMTAB.Lock(iRegion);
Result:=True;
break;
end;
end;
EZSEMTAB.Mutex:=False;
if Result then
begin
FLockList.Exclusive[iRow,iSlot]:=True;
FLockList.Shared[iRow,iSlot]:=True;
end else
begin
// We lost our shared hold when we put up the retry dialog form
FLockList.Shared[iRow,iSlot]:=False;
end;
end;