Source code of Windows XP (NT5)
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.

63 lines
1.5 KiB

  1. #include "stock.h"
  2. #pragma hdrstop
  3. #include "rpctimeout.h"
  4. WINOLEAPI CoCancelCall(IN DWORD dwThreadId, IN ULONG ulTimeout);
  5. WINOLEAPI CoEnableCallCancellation(IN LPVOID pReserved);
  6. WINOLEAPI CoDisableCallCancellation(IN LPVOID pReserved);
  7. void CRPCTimeout::_Callback(PVOID lpParameter, BOOLEAN)
  8. {
  9. CRPCTimeout *self = reinterpret_cast<CRPCTimeout *>(lpParameter);
  10. if (SUCCEEDED(CoCancelCall(self->_dwThreadId, 0)))
  11. {
  12. self->_fTimedOut = TRUE;
  13. }
  14. }
  15. #define DEFAULT_RPCTIMEOUT 5000 // totally arbitrary number
  16. #define REPEAT_RPCTIMEOUT 1000 // Re-cancel every second until disarmed
  17. void CRPCTimeout::Init()
  18. {
  19. _dwThreadId = GetCurrentThreadId();
  20. _fTimedOut = FALSE;
  21. _hrCancelEnabled = E_FAIL;
  22. _hTimer = NULL;
  23. }
  24. void CRPCTimeout::Arm(DWORD dwTimeout)
  25. {
  26. Disarm();
  27. if (dwTimeout == 0)
  28. {
  29. dwTimeout = DEFAULT_RPCTIMEOUT;
  30. }
  31. // If this fails, then we don't get a cancel thingie; oh well.
  32. _hrCancelEnabled = CoEnableCallCancellation(NULL);
  33. if (SUCCEEDED(_hrCancelEnabled))
  34. {
  35. _hTimer = SHSetTimerQueueTimer(NULL, _Callback, this,
  36. dwTimeout, REPEAT_RPCTIMEOUT, NULL, 0);
  37. }
  38. }
  39. void CRPCTimeout::Disarm()
  40. {
  41. if (SUCCEEDED(_hrCancelEnabled))
  42. {
  43. _hrCancelEnabled = E_FAIL;
  44. CoDisableCallCancellation(NULL);
  45. if (_hTimer)
  46. {
  47. SHCancelTimerQueueTimer(NULL, _hTimer);
  48. _hTimer = NULL;
  49. }
  50. }
  51. }