BUG: A Level 3 Volume Lock Might Deadlock on Windows 95
ID: Q176905
|
The information in this article applies to:
-
Microsoft Win32 Application Programming Interface (API), included with:
SYMPTOMS
Deadlock might occur when a Windows 95 application tries to take a level 3
volume lock. The following is a typical scenario:
Process A (32-bit) Process B (16-bit)
_________________________ _________________________
| | | |
| 1. Acquire level 2 lock | | |
| | | |
| | 2. Process A | |
| | preempted | |
| | ---------------> | |
| | | 3. Attempt a file write |
| | | |
| | | -acquire kernel32 |
| | | lock |
| | | |
| | | -IFS manager blocks |
| | | on write (Process A |
| | | owns level 2 lock) |
| | 4. Process A | |
| | rescheduled | |
| | <--------------- | |
| 5. Request for level 3 | | |
| lock blocks on | | |
| request for kernel32 | | |
| lock (owned by | | |
| Process B) | | |
|_________________________| |_________________________|
- Process A, a 32-bit Windows application, acquires a level 2 volume lock.
- Process A's running thread is preempted.
- Process B makes a 16-bit Windows API call requiring write access on the
locked drive. The API acquires the kernel32 lock prior to passing
the request to the IFS manager. The thread is blocked because it is
denied write access until process A releases the level 2 lock.
- Process A is rescheduled.
- Process A requests the level 3 volume lock. The level 3 lock first
tries to acquire the kernel32 lock. The thread subsequently blocks,
since the kernel32 lock is already owned by process B.
Both processes are now blocked, each one is waiting on a resource that the
other owns.
CAUSE
The deadlock takes place because the order in which the resources (write
access to the disk and the kernel32 lock) are requested differs between the
two processes and because the acquisition of these resources is not an
atomic transaction. Furthermore, the problem only seems to show up when
another process is performing 16-bit file I/O on the locked volume.
RESOLUTION
There is no viable workaround for 32-bit code. The Windows 95 disk
utilities avoid this problem by thunking to 16-bit code, thereby assuring
that the acquisition of the level 2 and level 3 volume locks is done
atomically.
Process A (32-bit) Process B (16-bit)
_________________________ _________________________
| | | |
| 1. Thunk to 16-bit code | | |
| | | |
| 2. Acquire level 2 lock | | |
| | | |
| 3. Acquire level 3 lock | | |
| (acquires kernel32 | | |
| lock) | | |
| | | |
| 4. Return from thunk | | |
| | | |
| | 5. Process A | |
| | preempted | |
| | ---------------> | |
| | | 6. Write blocks on |
| | | request for kernel32 |
| | | lock |
| | | |
| | 7. Process A | |
| | rescheduled | |
| | <--------------- | |
| | | |
| 8. Release level 3 lock | | |
| (releases kernel32 | | |
| lock) | | |
|_________________________| |_________________________|
There is no deadlock here, since process B is no longer blocked. In
reality, process A may be preempted between steps 2 and 3 above, but since
it will then own the Win16 mutex, no other 16-bit process may be scheduled.
Note that this will have consequences on the code design. To ensure
atomicity, the Win16 mutex must not be released between requests for the
level 2 and level 3 volume locks. Hence, these operations must be performed
from within the context of a single thunk.
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article. We are researching this bug and will post
new information here in the Microsoft Knowledge Base as it becomes
available.
MORE INFORMATION
Note that this problem is fixed in the Windows 95 OEM Service Release 2
(OSR2).
Additional query words:
disk I/O diskio access kernel base win95
Keywords : kbAPI kbKernBase kbGrpKernBase
Version : winnt:
Platform : winnt
Issue type : kbbug