Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
4.5 KiB

  1. /*-------------------------------------------------------------------
  2. | waitmask.c -
  3. 3-30-99 - fix cancel event operation(race-condition) to avoid
  4. potential bug-check on queued eventwait cancel.
  5. 11-24-98 - update event kdprint debug messages - kpb
  6. Copyright 1993-99 Comtrol Corporation. All rights reserved.
  7. |--------------------------------------------------------------------*/
  8. #include "precomp.h"
  9. /*------------------------------------------------------------------
  10. SerialCancelWait - (setup in ioctl.c currently, 3-28-98, kpb)
  11. This routine is used to cancel a irp that is waiting on a comm event.
  12. |-------------------------------------------------------------------*/
  13. VOID SerialCancelWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  14. {
  15. PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
  16. MyKdPrint(D_Ioctl,("CancelWait\n"))
  17. // take out, 3-30-99, kpb... Extension->IrpMaskLocation = NULL;
  18. if (Extension->CurrentWaitIrp)
  19. {
  20. PIRP Irp_tmp;
  21. MyKdPrint(D_Ioctl,("Cancel a Wait\n"))
  22. //***** add, 3-30-99, kpb, cause crash on read thread in dos box without
  23. // grab from ISR timer or interrupt routine.
  24. SyncUp(Driver.InterruptObject,
  25. &Driver.TimerLock,
  26. SerialGrabWaitFromIsr,
  27. Extension);
  28. //***** end add, 3-30-99
  29. // ExtTrace(Extension,D_Ioctl, "Cancel Event");
  30. Extension->CurrentWaitIrp->IoStatus.Information = 0;
  31. Extension->CurrentWaitIrp->IoStatus.Status = STATUS_CANCELLED;
  32. Irp_tmp = Extension->CurrentWaitIrp;
  33. IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
  34. Extension->CurrentWaitIrp = 0;
  35. IoReleaseCancelSpinLock(Irp->CancelIrql);
  36. SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
  37. }
  38. else
  39. {
  40. IoReleaseCancelSpinLock(Irp->CancelIrql);
  41. ExtTrace(Extension,D_Ioctl, "Err Cancel Event!");
  42. MyKdPrint(D_Ioctl,("No Wait to Cancel\n"))
  43. }
  44. }
  45. /*------------------------------------------------------------------
  46. SerialCompleteWait - called by isr.c via CommWaitDpc. It nulls out
  47. IrpMaskLocation to signal control passed back to us.
  48. |-------------------------------------------------------------------*/
  49. VOID SerialCompleteWait(IN PKDPC Dpc,IN PVOID DeferredContext,
  50. IN PVOID SystemContext1, IN PVOID SystemContext2)
  51. {
  52. PSERIAL_DEVICE_EXTENSION Extension = DeferredContext;
  53. KIRQL OldIrql;
  54. PIRP Irp_tmp;
  55. UNREFERENCED_PARAMETER(Dpc);
  56. UNREFERENCED_PARAMETER(SystemContext1);
  57. UNREFERENCED_PARAMETER(SystemContext2);
  58. MyKdPrint(D_Ioctl,("Complete Wait\n"))
  59. IoAcquireCancelSpinLock(&OldIrql);
  60. if (Extension->CurrentWaitIrp != 0)
  61. {
  62. MyKdPrint(D_Ioctl,("Complete a Wait\n"))
  63. ExtTrace2(Extension,D_Ioctl, "Event Done Got:%xH Mask:%xH",
  64. *(ULONG *) Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer,
  65. Extension->IsrWaitMask);
  66. Extension->WaitIsISRs = 0;
  67. Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
  68. // caller sets the ULONG bit flags indicating event at .SystemBuffer
  69. //*(ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer = 0;
  70. Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
  71. Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
  72. Irp_tmp = Extension->CurrentWaitIrp;
  73. IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
  74. Extension->CurrentWaitIrp = 0;
  75. IoReleaseCancelSpinLock(OldIrql);
  76. SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
  77. }
  78. else
  79. {
  80. MyKdPrint(D_Ioctl,("No wait to complete\n"))
  81. IoReleaseCancelSpinLock(OldIrql);
  82. }
  83. }
  84. /*------------------------------------------------------------------
  85. SerialGrabWaitFromIsr - Take back the wait packet from the ISR by
  86. reseting IrpMaskLocation in extension. Need to use a sync with
  87. isr/timer routine to avoid contention in multiprocessor environments.
  88. Called from sync routine or with timer spinlock held.
  89. App - Can set IrpMaskLocation to give read-irp handling to the ISR without
  90. syncing to ISR.
  91. ISR - Can reset ReadPending to give wait-irp handling back to app-time.
  92. If App wants to grab control of read-irp handling back from ISR, then
  93. it must sync-up with the isr/timer routine which has control.
  94. |-------------------------------------------------------------------*/
  95. BOOLEAN SerialGrabWaitFromIsr(PSERIAL_DEVICE_EXTENSION Extension)
  96. {
  97. Extension->WaitIsISRs = 0;
  98. Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
  99. return FALSE;
  100. }