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.

143 lines
3.6 KiB

  1. #include <wininetp.h>
  2. #include "hierarchy.h"
  3. P3PRequest::P3PRequest(P3PSignal *pSignal) {
  4. hComplete = CreateEvent(NULL, TRUE, FALSE, NULL);
  5. status = P3P_NotStarted;
  6. if (pSignal)
  7. retSignal = *pSignal;
  8. else
  9. memset(&retSignal, 0, sizeof(retSignal));
  10. InitializeCriticalSection(&csRequest);
  11. fRunning = TRUE;
  12. fCancelled = FALSE;
  13. fIOBound = FALSE;
  14. }
  15. P3PRequest::~P3PRequest() {
  16. CloseHandle(hComplete);
  17. DeleteCriticalSection(&csRequest);
  18. }
  19. void P3PRequest::Free() {
  20. EnterCriticalSection(&csRequest);
  21. if (!fRunning) {
  22. /* Important: leave critical-section first...
  23. self-destruction ("delete this") will free the CS */
  24. LeaveCriticalSection(&csRequest);
  25. delete this;
  26. return;
  27. }
  28. fCancelled = TRUE;
  29. BOOL fBlocked = fIOBound;
  30. LeaveCriticalSection(&csRequest);
  31. /* If request is CPU-bound, wait until it completes or aborts.
  32. Returning before that point would mean that client can free
  33. parameters passed into the request, causing worker thread to
  34. access deallocated resources */
  35. if (!fBlocked)
  36. waitForCompletion();
  37. }
  38. /* block until the request is finished */
  39. void P3PRequest::waitForCompletion() {
  40. WaitForSingleObject(hComplete, INFINITE);
  41. }
  42. /* this wrapper function calls execute and signals the completion event
  43. afterwards. its invoked by the static function ExecRequest */
  44. int P3PRequest::run() {
  45. CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  46. status = P3P_InProgress;
  47. __try {
  48. status = execute();
  49. } __except (EXCEPTION_EXECUTE_HANDLER) {
  50. /* catch exception thrown from cancelled request */
  51. status = P3P_Cancelled;
  52. }
  53. ENDEXCEPT
  54. CoUninitialize();
  55. return status;
  56. }
  57. unsigned long __stdcall P3PRequest::ExecRequest(void *pv) {
  58. P3PRequest *pRequest = (P3PRequest*) pv;
  59. int status = pRequest->run();
  60. EnterCriticalSection(& pRequest->csRequest);
  61. /* modify state of the request */
  62. pRequest->fRunning = FALSE;
  63. /* remember whether the request is cancelled.
  64. we cannot examine pRequest object after leaving the critical
  65. section because of possible race condition where FreeP3PObject()
  66. can invoke the destructor. */
  67. BOOL fWasCancelled = pRequest->fCancelled;
  68. /* signal callers that request is complete */
  69. if (!fWasCancelled) {
  70. P3PSignal retSignal = pRequest->retSignal;
  71. if (retSignal.hEvent)
  72. SetEvent(retSignal.hEvent);
  73. if (retSignal.hwnd)
  74. PostMessage(retSignal.hwnd, retSignal.message, status, (WPARAM) retSignal.pContext);
  75. }
  76. SetEvent(pRequest->hComplete);
  77. LeaveCriticalSection(& pRequest->csRequest);
  78. /* A cancelled request will be freed on the same thread
  79. that it executed on. All other threads get freed on the
  80. thread where FreeP3PObject() is invoked. */
  81. if (fWasCancelled)
  82. delete pRequest;
  83. return status;
  84. }
  85. void P3PRequest::enterIOBoundState() {
  86. EnterCriticalSection(&csRequest);
  87. if (!fCancelled)
  88. fIOBound = TRUE;
  89. BOOL fWasCancelled = fCancelled;
  90. LeaveCriticalSection(&csRequest);
  91. /* throw exception if request has been cancelled */
  92. if (fWasCancelled)
  93. throw P3P_Cancelled;
  94. }
  95. void P3PRequest::leaveIOBoundState() {
  96. EnterCriticalSection(&csRequest);
  97. fIOBound = FALSE;
  98. BOOL fWasCancelled = fCancelled;
  99. LeaveCriticalSection(&csRequest);
  100. /* throw exception if request has been cancelled */
  101. if (fWasCancelled)
  102. throw P3P_Cancelled;
  103. }