ReactOS  0.4.14-dev-50-g13bb5e2
lock.c File Reference
#include "classp.h"
Include dependency graph for lock.c:

Go to the source code of this file.

Classes

struct  _REMOVE_TRACKING_BLOCK
 

Typedefs

typedef struct _REMOVE_TRACKING_BLOCK REMOVE_TRACKING_BLOCK
 
typedef struct _REMOVE_TRACKING_BLOCKPREMOVE_TRACKING_BLOCK
 

Functions

ULONG NTAPI ClassAcquireRemoveLockEx (IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PVOID Tag, IN PCSTR File, IN ULONG Line)
 
VOID NTAPI ClassReleaseRemoveLock (IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
 
VOID NTAPI ClassCompleteRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
 

Variables

LONG LockHighWatermark = 0
 
LONG LockLowWatermark = 0
 
LONG MaxLockedMinutes = 5
 

Typedef Documentation

◆ PREMOVE_TRACKING_BLOCK

◆ REMOVE_TRACKING_BLOCK

Function Documentation

◆ ClassAcquireRemoveLockEx()

ULONG NTAPI ClassAcquireRemoveLockEx ( IN PDEVICE_OBJECT  DeviceObject,
IN OPTIONAL PVOID  Tag,
IN PCSTR  File,
IN ULONG  Line 
)

Definition at line 81 of file lock.c.

87 {
89  LONG lockValue;
90 
91 
92 
93  //
94  // Grab the remove lock
95  //
96  lockValue = InterlockedIncrement(&commonExtension->RemoveLock);
97 
98  #if DBG
99 
100  DebugPrint((ClassDebugRemoveLock, "ClassAcquireRemoveLock: "
101  "Acquired for Object %p & irp %p - count is %d\n",
102  DeviceObject, Tag, lockValue));
103 
104  ASSERTMSG("ClassAcquireRemoveLock - lock value was negative : ",
105  (lockValue > 0));
106 
107  ASSERTMSG("RemoveLock increased to meet LockHighWatermark",
108  ((LockHighWatermark == 0) ||
109  (lockValue != LockHighWatermark)));
110 
111  if (commonExtension->IsRemoved != REMOVE_COMPLETE){
112  PREMOVE_TRACKING_BLOCK trackingBlock;
113 
114  trackingBlock = ExAllocatePool(NonPagedPool,
115  sizeof(REMOVE_TRACKING_BLOCK));
116 
117  if(trackingBlock == NULL) {
118 
119  KIRQL oldIrql;
120 
121  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
122  &oldIrql);
123 
124  commonExtension->RemoveTrackingUntrackedCount++;
125 
126  DebugPrint((ClassDebugWarning, ">>>>>ClassAcquireRemoveLock: "
127  "Cannot track Tag %p - currently %d untracked requests\n",
128  Tag, commonExtension->RemoveTrackingUntrackedCount));
129 
130  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock,
131  oldIrql);
132  }
133  else {
134  PREMOVE_TRACKING_BLOCK *removeTrackingList =
135  (PREMOVE_TRACKING_BLOCK*)&commonExtension->RemoveTrackingList;
136 
137  KIRQL oldIrql;
138 
139  trackingBlock->Tag = Tag;
140 
141  trackingBlock->File = File;
142  trackingBlock->Line = Line;
143 
144  KeQueryTickCount((&trackingBlock->TimeLocked));
145 
146  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
147  &oldIrql);
148 
149  while(*removeTrackingList != NULL) {
150 
151  if((*removeTrackingList)->Tag > Tag) {
152  break;
153  }
154 
155  if((*removeTrackingList)->Tag == Tag) {
156 
157  DebugPrint((ClassDebugError, ">>>>>ClassAcquireRemoveLock: "
158  "already tracking Tag %p\n", Tag));
159  DebugPrint((ClassDebugError, ">>>>>ClassAcquireRemoveLock: "
160  "acquired in file %s on line %d\n",
161  (*removeTrackingList)->File,
162  (*removeTrackingList)->Line));
163  ASSERT(FALSE);
164  }
165 
166  removeTrackingList = &((*removeTrackingList)->NextBlock);
167  }
168 
169  trackingBlock->NextBlock = *removeTrackingList;
170  *removeTrackingList = trackingBlock;
171 
172  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock,
173  oldIrql);
174 
175  }
176  }
177 
178  #endif
179 
180  return (commonExtension->IsRemoved);
181 }
LONG LockHighWatermark
Definition: lock.c:27
#define REMOVE_COMPLETE
Definition: classpnp.h:95
UCHAR KIRQL
Definition: env_spec_w32.h:591
long LONG
Definition: pedump.c:60
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct _REMOVE_TRACKING_BLOCK * NextBlock
Definition: lock.c:35
LARGE_INTEGER TimeLocked
Definition: lock.c:37
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: ncftp.h:79
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define InterlockedIncrement
Definition: armddk.h:53
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
Definition: File.h:15
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:579

◆ ClassCompleteRequest()

VOID NTAPI ClassCompleteRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN CCHAR  PriorityBoost 
)

Definition at line 376 of file lock.c.

381 {
382 
383  #if DBG
385  PREMOVE_TRACKING_BLOCK *listEntry =
386  (PREMOVE_TRACKING_BLOCK*)&commonExtension->RemoveTrackingList;
387 
388  KIRQL oldIrql;
389 
390  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
391  &oldIrql);
392 
393  while(*listEntry != NULL) {
394 
395  if((*listEntry)->Tag == Irp) {
396  break;
397  }
398 
399  listEntry = &((*listEntry)->NextBlock);
400  }
401 
402  if(*listEntry != NULL) {
403 
404  DebugPrint((ClassDebugError, ">>>>>ClassCompleteRequest: "
405  "Irp %p completed while still holding the remove lock\n",
406  Irp));
407  DebugPrint((ClassDebugError, ">>>>>ClassCompleteRequest: "
408  "Lock acquired in file %s on line %d\n",
409  (*listEntry)->File, (*listEntry)->Line));
410  ASSERT(FALSE);
411  }
412 
413  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
414  #endif
415 
417  return;
418 } // end ClassCompleteRequest()
_In_ PIRP Irp
Definition: csq.h:116
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ CCHAR PriorityBoost
Definition: iofuncs.h:763
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:579

Referenced by CdRomCompleteIrpAndStartNextPacketSafely(), CdRomDeviceControlDispatch(), CdRomStartIo(), CdRomTickHandler(), ClassCheckVerifyComplete(), ClassCreateClose(), ClassDeviceControl(), ClassDeviceControlDispatch(), ClassDispatchPnp(), ClassDispatchPower(), ClassInternalIoControl(), ClassIoCompleteAssociated(), ClassMinimalPowerHandler(), ClasspMcnControl(), ClasspStartIo(), ClassReadWrite(), ClassSendSrbAsynchronous(), ClassShutdownFlush(), ClassSystemControl(), ClassWmiCompleteRequest(), DiskDeviceControl(), DiskIoctlVerify(), DiskShutdownFlush(), ScsiFlopDeviceControl(), and TransferPktComplete().

◆ ClassReleaseRemoveLock()

VOID NTAPI ClassReleaseRemoveLock ( IN PDEVICE_OBJECT  DeviceObject,
IN OPTIONAL PIRP  Tag 
)

Definition at line 212 of file lock.c.

216 {
218  LONG lockValue;
219 
220  #if DBG
221  PREMOVE_TRACKING_BLOCK *listEntry =
222  (PREMOVE_TRACKING_BLOCK*)&commonExtension->RemoveTrackingList;
223 
224  BOOLEAN found = FALSE;
225 
227 
228  BOOLEAN isRemoved = (commonExtension->IsRemoved == REMOVE_COMPLETE);
229 
230  KIRQL oldIrql;
231 
232  if(isRemoved) {
233  DBGTRAP(("ClassReleaseRemoveLock: REMOVE_COMPLETE set; this should never happen"));
234  InterlockedDecrement(&(commonExtension->RemoveLock));
235  return;
236  }
237 
238  //
239  // Check the tick count and make sure this thing hasn't been locked
240  // for more than MaxLockedMinutes.
241  //
242 
243  maxCount = KeQueryTimeIncrement() * 10; // microseconds
244  maxCount *= 1000; // milliseconds
245  maxCount *= 1000; // seconds
246  maxCount *= 60; // minutes
248 
249  DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
250  "maxCount = %0I64x\n", maxCount));
251 
252  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
253  &oldIrql);
254 
255  while(*listEntry != NULL) {
256 
258  LARGE_INTEGER difference;
259 
260  block = *listEntry;
261 
262  KeQueryTickCount((&difference));
263 
264  difference.QuadPart -= block->TimeLocked.QuadPart;
265 
266  DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
267  "Object %p (tag %p) locked for %I64d ticks\n",
268  DeviceObject, block->Tag, difference.QuadPart));
269 
270  if(difference.QuadPart >= maxCount) {
271 
272  DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
273  "Object %p (tag %p) locked for %I64d ticks - TOO LONG\n",
274  DeviceObject, block->Tag, difference.QuadPart));
275  DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
276  "Lock acquired in file %s on line %d\n",
277  block->File, block->Line));
278  ASSERT(FALSE);
279  }
280 
281  if((found == FALSE) && ((*listEntry)->Tag == Tag)) {
282 
283  *listEntry = block->NextBlock;
284  ExFreePool(block);
285  found = TRUE;
286 
287  } else {
288 
289  listEntry = &((*listEntry)->NextBlock);
290 
291  }
292  }
293 
294  if(!found) {
295  if(commonExtension->RemoveTrackingUntrackedCount == 0) {
296  DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
297  "Couldn't find Tag %p in the lock tracking list\n",
298  Tag));
299  ASSERT(FALSE);
300  } else {
301  DebugPrint((ClassDebugError, ">>>>>ClassReleaseRemoveLock: "
302  "Couldn't find Tag %p in the lock tracking list - "
303  "may be one of the %d untracked requests still "
304  "outstanding\n",
305  Tag,
306  commonExtension->RemoveTrackingUntrackedCount));
307 
308  commonExtension->RemoveTrackingUntrackedCount--;
309  ASSERT(commonExtension->RemoveTrackingUntrackedCount >= 0);
310  }
311  }
312 
313  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock,
314  oldIrql);
315 
316  #endif
317 
318  lockValue = InterlockedDecrement(&commonExtension->RemoveLock);
319 
320  DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
321  "Released for Object %p & irp %p - count is %d\n",
322  DeviceObject, Tag, lockValue));
323 
324  ASSERT(lockValue >= 0);
325 
326  ASSERTMSG("RemoveLock decreased to meet LockLowWatermark",
327  ((LockLowWatermark == 0) || !(lockValue == LockLowWatermark)));
328 
329  if(lockValue == 0) {
330 
331  ASSERT(commonExtension->IsRemoved);
332 
333  //
334  // The device needs to be removed. Signal the remove event
335  // that it's safe to go ahead.
336  //
337 
338  DebugPrint((ClassDebugRemoveLock, "ClassReleaseRemoveLock: "
339  "Release for object %p & irp %p caused lock to go to zero\n",
340  DeviceObject, Tag));
341 
342  KeSetEvent(&commonExtension->RemoveEvent,
344  FALSE);
345 
346  }
347  return;
348 }
static unsigned int block
Definition: xmlmemory.c:118
#define TRUE
Definition: types.h:120
#define REMOVE_COMPLETE
Definition: classpnp.h:95
LONG MaxLockedMinutes
Definition: lock.c:29
ULONG NTAPI KeQueryTimeIncrement(VOID)
Definition: clock.c:153
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
UCHAR KIRQL
Definition: env_spec_w32.h:591
long LONG
Definition: pedump.c:60
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define DBGTRAP(args_in_parens)
Definition: debug.h:137
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
LONG LockLowWatermark
Definition: lock.c:28
int64_t LONGLONG
Definition: typedefs.h:66
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InterlockedDecrement
Definition: armddk.h:52
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
GLsizei maxCount
Definition: glext.h:6042
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
#define IO_NO_INCREMENT
Definition: iotypes.h:566
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:579
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by CdRomCompleteIrpAndStartNextPacketSafely(), CdRomDeviceControlDispatch(), CdRompFlushDelayedList(), CdRomShutdownFlushCompletion(), CdRomStartIo(), CdRomTickHandler(), CdRomXACompletion(), ClassAsynchronousCompletion(), ClassCheckVerifyComplete(), ClassCreateClose(), ClassDeviceControl(), ClassDeviceControlDispatch(), ClassDispatchPnp(), ClassDispatchPower(), ClassInternalIoControl(), ClassIoComplete(), ClassIoCompleteAssociated(), ClassMinimalPowerHandler(), ClasspFailurePredict(), ClasspInitializeGesn(), ClasspMcnControl(), ClasspMediaChangeDetectionCompletion(), ClasspPowerDownCompletion(), ClasspPowerHandler(), ClasspPowerUpCompletion(), ClasspPrepareMcnIrp(), ClasspStartIo(), ClasspTimerTick(), ClassReadWrite(), ClassReleaseQueueCompletion(), ClassRemoveDevice(), ClassSendSrbAsynchronous(), ClassShutdownFlush(), ClassSystemControl(), ClassWmiCompleteRequest(), DiskDeviceControl(), DiskInfoExceptionCheck(), DiskInfoExceptionComplete(), DiskIoctlVerify(), DiskReregWorker(), DiskShutdownFlush(), ScsiFlopDeviceControl(), ToshibaProcessErrorCompletion(), and TransferPktComplete().

Variable Documentation

◆ LockHighWatermark

LONG LockHighWatermark = 0

Definition at line 27 of file lock.c.

Referenced by ClassAcquireRemoveLockEx().

◆ LockLowWatermark

LONG LockLowWatermark = 0

Definition at line 28 of file lock.c.

Referenced by ClassReleaseRemoveLock().

◆ MaxLockedMinutes

LONG MaxLockedMinutes = 5

Definition at line 29 of file lock.c.

Referenced by ClassReleaseRemoveLock(), and IoInitializeRemoveLockEx().