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.

145 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. timer.c
  5. Abstract:
  6. Timer thread to monitor connection progress in the
  7. automatic connection driver (acd.sys).
  8. Author:
  9. Anthony Discolo (adiscolo) 25-Apr-1995
  10. Environment:
  11. Kernel Mode
  12. Revision History:
  13. --*/
  14. #include <ndis.h>
  15. #include <cxport.h>
  16. #include <tdi.h>
  17. #include <tdikrnl.h>
  18. #include <tdistat.h>
  19. #include <tdiinfo.h>
  20. #include <acd.h>
  21. #include "acdapi.h"
  22. #include "table.h"
  23. #include "acddefs.h"
  24. #include "debug.h"
  25. //
  26. // Imported routines.
  27. //
  28. VOID
  29. AcdSignalCompletionCommon(
  30. IN PACD_CONNECTION pConnection,
  31. IN BOOLEAN fSuccess
  32. );
  33. //
  34. // Keep track how long the user-space
  35. // process has been attempting a connection.
  36. //
  37. #define ACD_MAX_TIMER_CALLS 3*60 // 3 minutes
  38. //
  39. // We give the user-space process
  40. // some slack on missed pings.
  41. //
  42. #define ACD_MAX_MISSED_PINGS 40 // 20 seconds
  43. VOID
  44. AcdConnectionTimer(
  45. IN PDEVICE_OBJECT pDeviceObject,
  46. IN PVOID pContext
  47. )
  48. {
  49. PLIST_ENTRY pEntry;
  50. PACD_CONNECTION pConnection;
  51. BOOLEAN bCancel = FALSE;
  52. //
  53. // Acquire the spin lock.
  54. // We're guaranteed to be at DPC
  55. // since this is a timer routine.
  56. //
  57. KeAcquireSpinLockAtDpcLevel(&AcdSpinLockG);
  58. //
  59. // If the user-space process responsible
  60. // for creating the connection hasn't
  61. // pinged us in a while, or if it hasn't
  62. // created a connection in 3 minutes,
  63. // cancel all the pending requests.
  64. //
  65. for (pEntry = AcdConnectionQueueG.Flink;
  66. pEntry != &AcdConnectionQueueG;
  67. pEntry = pEntry->Flink)
  68. {
  69. pConnection = CONTAINING_RECORD(pEntry, ACD_CONNECTION, ListEntry);
  70. IF_ACDDBG(ACD_DEBUG_TIMER) {
  71. PACD_COMPLETION pCompletion;
  72. AcdPrint((
  73. "AcdConnectionTimer: pConnection=0x%x, fNotif=%d, szAddr=",
  74. pConnection,
  75. pConnection->fNotif));
  76. pCompletion = CONTAINING_RECORD(pConnection->CompletionList.Flink, ACD_COMPLETION, ListEntry);
  77. AcdPrintAddress(&pCompletion->notif.addr);
  78. AcdPrint((", nTimerCalls=%d, nMissedPings=%d\n",
  79. pConnection->ulTimerCalls,
  80. pConnection->ulMissedPings));
  81. }
  82. //
  83. // If we haven't reported the connection to
  84. // user space yet, or it is in the process of
  85. // being completed, then don't time it out.
  86. //
  87. if (!pConnection->fNotif || pConnection->fCompleting)
  88. continue;
  89. pConnection->ulTimerCalls++;
  90. if (pConnection->fProgressPing)
  91. pConnection->ulMissedPings = 0;
  92. else
  93. pConnection->ulMissedPings++;
  94. if (pConnection->ulTimerCalls >= ACD_MAX_TIMER_CALLS ||
  95. pConnection->ulMissedPings >= ACD_MAX_MISSED_PINGS)
  96. {
  97. IF_ACDDBG(ACD_DEBUG_TIMER) {
  98. AcdPrint((
  99. "AcdConnectionTimer: canceling pConnection=0x%x\n",
  100. pConnection));
  101. }
  102. //
  103. // Set the completion-in-progress flag so
  104. // this request cannot be completed after
  105. // we release the spin lock.
  106. //
  107. pConnection->fCompleting = TRUE;
  108. bCancel = TRUE;
  109. break;
  110. }
  111. }
  112. //
  113. // Release the spin lock.
  114. //
  115. KeReleaseSpinLockFromDpcLevel(&AcdSpinLockG);
  116. //
  117. // We now process all the canceled requests.
  118. //
  119. if (bCancel)
  120. AcdSignalCompletionCommon(pConnection, FALSE);
  121. } // AcdConnectionTimer
  122.