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.

125 lines
2.2 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. procblk.c
  5. Abstract:
  6. This module implements process block and unblock
  7. Author:
  8. Mark Lucovsky (markl) 30-Mar-1989
  9. Revision History:
  10. --*/
  11. #include "psxsrv.h"
  12. NTSTATUS
  13. BlockProcess(
  14. IN PPSX_PROCESS p,
  15. IN PVOID Context,
  16. IN INTHANDLER Handler,
  17. IN PPSX_API_MSG m,
  18. IN PLIST_ENTRY BlockList OPTIONAL,
  19. IN PRTL_CRITICAL_SECTION CriticalSectionToRelease OPTIONAL
  20. )
  21. {
  22. PINTCB IntCb;
  23. PPSX_API_MSG NewM;
  24. int Sig;
  25. IntCb = RtlAllocateHeap(PsxHeap, 0, sizeof(INTCB));
  26. if (NULL == IntCb) {
  27. return STATUS_NO_MEMORY;
  28. }
  29. NewM = RtlAllocateHeap(PsxHeap, 0, sizeof(PSX_API_MSG));
  30. if (NULL == NewM) {
  31. RtlFreeHeap(PsxHeap, 0, IntCb);
  32. return STATUS_NO_MEMORY;
  33. }
  34. *NewM = *m;
  35. IntCb->IntHandler = Handler;
  36. IntCb->IntMessage = NewM;
  37. IntCb->IntContext = Context;
  38. RtlEnterCriticalSection(&BlockLock);
  39. p->IntControlBlock = IntCb;
  40. if (ARGUMENT_PRESENT(BlockList)) {
  41. InsertTailList(BlockList, &IntCb->Links);
  42. } else {
  43. InsertTailList(&DefaultBlockList, &IntCb->Links);
  44. }
  45. AcquireProcessLock(p);
  46. //
  47. // Check for signals
  48. //
  49. if (0 != (Sig = PsxCheckPendingSignals(p))) {
  50. ReleaseProcessLock(p);
  51. //
  52. // Block is interrupted by a signal
  53. //
  54. if (ARGUMENT_PRESENT(CriticalSectionToRelease)) {
  55. RtlLeaveCriticalSection(CriticalSectionToRelease);
  56. }
  57. UnblockProcess(p, SignalInterrupt, TRUE, Sig);
  58. return STATUS_SUCCESS;
  59. }
  60. if (ARGUMENT_PRESENT(CriticalSectionToRelease)) {
  61. RtlLeaveCriticalSection(CriticalSectionToRelease);
  62. }
  63. ReleaseProcessLock(p);
  64. RtlLeaveCriticalSection(&BlockLock);
  65. return STATUS_SUCCESS;
  66. }
  67. BOOLEAN
  68. UnblockProcess(
  69. IN PPSX_PROCESS p,
  70. IN PSX_INTERRUPTREASON InterruptReason,
  71. IN BOOLEAN BlockLockHeld,
  72. IN int Signal // Signal causing wakeup, if any
  73. )
  74. {
  75. PINTCB IntCb;
  76. if (!BlockLockHeld) {
  77. RtlEnterCriticalSection(&BlockLock);
  78. }
  79. if (p->IntControlBlock) {
  80. IntCb = p->IntControlBlock;
  81. RemoveEntryList(&IntCb->Links);
  82. p->IntControlBlock = (PINTCB) NULL;
  83. (IntCb->IntHandler)(p,IntCb,InterruptReason,Signal);
  84. return TRUE;
  85. }
  86. if (!BlockLockHeld) {
  87. RtlLeaveCriticalSection(&BlockLock);
  88. }
  89. return FALSE;
  90. }