PRB: Byte-Range File Locking Deadlock Condition

Last reviewed: April 18, 1997
Article ID: Q117223
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with: - Microsoft Windows NT versions 3.1, 3.5

SYMPTOMS

It is possible for a thread in a multithreaded Win32-based application to block while doing a LockFile() or LockFileEx() API call, even when the region of the file the thread has requested is not locked by another thread.

NOTE: If performance-monitoring tools (such as PERFMON) are used to examine the status of existing threads and the Thread State indicates that the thread is waiting and the Thread Wait Reason shows that it is the executive that the thread is waiting on, this is probably not an indication that a deadlock has occurred, because threads are often in this state for other reasons. Also, if the Thread State indicates that the thread is not waiting, then a deadlock has probably not occurred.

CAUSE

There is a small window of time during which a multithreaded application is vulnerable to this condition. Specifically, if one thread (call it Thread1) is in the process of unlocking a currently locked byte range within a file while a second thread (Thread2) is in the process of obtaining a lock on that same byte range using the same file handle and without specifying the flag LOCKFILE_FAIL_IMMEDIATELY, Thread1 can block, waiting for the region to become available. Ordinarily, when unlocking takes place, blocked threads are released; but in this critical window of time, it is possible for Thread2 to unlock the byte range without Thread1 being released. Thus, Thread1 never resumes operation despite the fact that there is no apparent fault in the logic of the program.

RESOLUTION

The deadlock condition described above can only come about if multiple threads are concurrently doing synchronous I/O using the same file handle.

To avoid the problem, you have three options:

  • Each thread can obtain its own handle to the file either through the use of the DuplicateHandle() API or through multiple calls to the CreateFile() API.

    -or-

  • The threads can perform asynchronous I/O. This also requires the application developer to provide some form of explicit synchronization to coordinate access to the file by the threads.

    -or-

  • The threads can specify LOCKFILE_FAIL_IMMEDIATELY and then loop until a retry succeeds if the lock request fails. This option is the least desirable because it incurs significant CPU use overhead.

REFERENCES

For more information about threads, files, and file handles, see the following sections in the "Win32 SDK Programmer's Reference," volume 2, part 3, "System Services":

  • Chapter 43.1.6, "Synchronizing Execution of Multiple Threads"
  • Chapter 45.2.2, "Reading, Writing, and Locking Files"
  • Chapter 48.3, "Kernel Objects"


Keywords : BseMisc kbprg
Version : 3.10 3.50
Platform : NT WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: April 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.