Locking File


Locking a region of a file gives the locking process exclusive access to the specified region, that is, denies all other processes both read and write access to the region. Locking is used typically in situations when multiple processes or threads have access to the same file and therefore can interfere. When file region is locked, access to it is serialized, guaranteeing that data is processed in a consistent manner and will not be corrupted. IXFile supports both automatic and manual locking that can be used separately or collectively, depending on your needs.

Automatic file locking is specified during initialization and can be activated for reading, writing or both; see Initialize for information on how to do this. When automatic locking is enabled, region in file of appropriate size and position is locked before read or write operation takes place. After data is accessed and operation completes, region is unlocked. Automatic locking is always performed with regard to data buffer which can contain partial data. If data is entirely in buffer, no additional locking takes place because region is locked when buffer is flushed or refilled. If data does not fit or is partially in buffer, entire data region is locked before read or write operation takes place, and lock remains active until all requested data is completely read or written. Please note that locking is performed whenever file data needs to be accessed, regardless of actual user activity - locking is enforced not only on Get and Put operations but also on Flush, SetSize, Shrink, Expand, Find and all other activities which explicitly or implicitly access file data. Automatic locking always concerns single operation of reading or writing data and therefore cannot be used for exclusive read-modify-write operation; for such processing manual locking must be used. Automatic locking makes use of multiple locking (see below) to allow developers to combine it with manual locking.

Manual locking is used whenever specific file region must be locked, and stay locked as long as required. With LockByte, LockShort, LockLong, LockFloat, LockDouble, LockText, LockUnicodeText, LockVariant and LockBinary methods, you can lock data regions of various types supported by IXFile. Size of file region is calculated internally based on data type and number of elements to lock. All methods return lock handle that identifies locked region (its size and position) and this handle should be finally passed to UnLock method for unlocking. Manual locking can be used with or without multiple locking feature (see below). When multiple locking is used, file regions can overlap and automatic locking can be used collectively if desired. When disabled, regions cannot overlap and are always directly mapped to physical locks. In such case, however, it is user responsibility to properly handle them.

Multiple locking allows locking the same region or its parts many times; single IXFile object can lock as many overlapping file regions as needed, without regard to their influence on each other. In other words you can lock a region that is already locked and then properly unlock it. This is possible because map of locked regions is maintained internally by the object to guarantee correct order of unlocking. File region is physically unlocked only when there are no dependent locks active. Because of it, however, unlocking may not result in physical unlocking of file region; in other words you must assume that after calling UnLock method, specified region can be still physically locked. Please note that multiple locking is allowed only for the same IXFile object - you cannot lock region that overlapps region locked by another application, thread or other IXFile objects.

Locked region should be unlocked as soon as possible to allow other processes perform their operations and avoid deadlocks. To unlock file region use UnLock method, passing lock handle obtained from one of the locking methods. When file is being closed or detached from the object, all its locks are automatically removed.

Examples

C++

// error handling is omitted for clarity


  int main(int, char**)
  {
   IFile ixf;
   long lock1, lock2, lock3;
   short data;
   char txt[256];

   ixf.SetLicenseKey("YOURLICENSEKEY");

// initialize object and open file

   ixf.Initialize(); 
   ixf.Open("test.bin"); 

// lock 100 bytes starting from position 10
// multilocking is disabled

   lock1 = ixf.LockByte(10, 100, FALSE);

// lock another 100 bytes starting from position 150
// multilocking is also disabled
// regions do not overlap so operation succeeds

   lock2 = ixf.LockByte(150, 100, FALSE);

// lock 200 bytes starting from position 0
// region overlaps previously locked regions
// but multilocking is enabled so operation succeeds
// physically locks TWO regions: 0-10 and 110-150
// remaining regions are already locked by lock1 and lock2 

   lock3 = ixf.LockByte(0, 200, TRUE);

    .
    .
    .

// remove first lock
// region remains locked because
// dependent (third) lock is still active

   ixf.UnLock(lock1);

// remove third lock
// physically unlocks following regions:
// 0-10 (its own)
// 110-150 (its own)
// 10-100 (first lock region not physically removed in previous operation)
// last region 150-200 is still locked by second lock

   ixf.UnLock(lock3);

// remove second lock
// physically unlocks entire region
// because there are no dependent locks

   ixf.UnLock(lock2);

    .
    .
    .

// reinitialize the same object for reading 
// and enable automatic locking on read operations

   ixf.Initialize(IXF_MODE_READ | IXF_MODE_READLOCK | IXF_MODE_CLOSE); 

// open data file

   ixf.Open("test.bin"); 

// lock 100 bytes starting from position 10
// multilocking is disabled

   lock1 = ixf.LockByte(10, 100, FALSE);

// read NULL-terminated string starting from position 50
// and automatically lock appropriate region
// physically locks region 110-EOF, remaining region 
// is already locked by first lock
// file is locked up to EOF - length of text is not known
// operation succeeds because automatic locking
// uses multiple locking feature 
// on completion first region remains locked

   ixf.GetText(txt, 256, 50, IXF_TEXT_NULLTERM);

// read short integer at position 75
// and automatically lock appropriate region (2 bytes)
// physically does not lock anything because 
// entire data region is already locked by first lock

   ixf.GetShort(&data, 1, 75);

// remove first lock
// physically unlocks entire region
// because there are no dependent locks

   ixf.UnLock(lock1);

   return(0);

  }

BASIC

' error handling is omitted for clarity


  Sub Main()

   Dim ixf As IXFile
   Dim lock1 As Long, lock2 As Long, lock3 As Long
   Dim data as Integer
   Dim txt As String

   Set ixf = New IXFile
   ixf.SetLicenseKey "YOURLICENSEKEY"

' initialize object and open file

   ixf.Initialize 
   ixf.Open "test.bin"

' lock 100 bytes starting from position 10
' multilocking is disabled

   lock1 = ixf.LockByte(10, 100, False)

' lock another 100 bytes starting from position 150
' multilocking is disabled
' regions do not overlap so operation succeeds

   lock2 = ixf.LockByte(150, 100, False)

' lock 200 bytes starting from position 0
' region overlaps previous regions
' but multilock is enabled so operation succeeds
' physically locks TWO regions: 0-10 and 110-150
' remaining regiona are already locked by lock1 and lock2 

   lock3 = ixf.LockByte(0, 200, True)

    .
    .
    .

' remove first lock
' region remains locked because 
' dependent (third) lock is still active

   ixf.UnLock lock1

' remove third lock
' physically unlocks following regions:
' 0-10 (its own)
' 110-150 (its own)
' 10-100 (first lock region not physically removed in previous operation)
' last region 150-200 is still locked by second lock

   ixf.UnLock lock3

' remove second lock
' physically unlocks entire region
' because there are no dependent locks

   ixf.UnLock lock2

    .
    .
    .

' reinitialize the same object for reading 
' also enable automatic locking on read

   ixf.Initialize IXF_MODE_READ Or IXF_MODE_READLOCK Or IXF_MODE_CLOSE

' open data file

   ixf.Open "test.bin"

' lock 100 bytes starting from position 10
' multilocking is disabled

   lock1 = ixf.LockByte(10, 100, False)

' read NULL-terminated string starting from position 50
' and automatically lock appropriate region
' physically locks region 110-EOF
' remaining region is already locked by first lock
' file is locked up to EOF (length of text is not known)
' operation succeeds because automatic locking
' uses multiple locking feature 
' on completion first region remains locked

   ixf.GetText txt, 256, 50, IXF_TEXT_NULLTERM

' read short integer at position 75
' and automatically lock appropriate region (2 bytes)
' physically does not lock anything because 
' entire data region is already locked by first lock

   ixf.GetShort data, 1, 75

' remove first lock
' physically unlocks entire region
' because there are no dependent locks

   ixf.UnLock lock1

  End Sub

See Also

LockByte, LockShort, LockLong, LockFloat, LockDouble, LockText, LockUnicodeText, LockVariant, LockBinary, UnLock