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;


Reply via email to