126 lines
2.2 KiB
C
126 lines
2.2 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1989 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
procblk.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements process block and unblock
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mark Lucovsky (markl) 30-Mar-1989
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "psxsrv.h"
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
BlockProcess(
|
||
|
IN PPSX_PROCESS p,
|
||
|
IN PVOID Context,
|
||
|
IN INTHANDLER Handler,
|
||
|
IN PPSX_API_MSG m,
|
||
|
IN PLIST_ENTRY BlockList OPTIONAL,
|
||
|
IN PRTL_CRITICAL_SECTION CriticalSectionToRelease OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
PINTCB IntCb;
|
||
|
PPSX_API_MSG NewM;
|
||
|
int Sig;
|
||
|
|
||
|
IntCb = RtlAllocateHeap(PsxHeap, 0, sizeof(INTCB));
|
||
|
if (NULL == IntCb) {
|
||
|
return STATUS_NO_MEMORY;
|
||
|
}
|
||
|
|
||
|
NewM = RtlAllocateHeap(PsxHeap, 0, sizeof(PSX_API_MSG));
|
||
|
if (NULL == NewM) {
|
||
|
RtlFreeHeap(PsxHeap, 0, IntCb);
|
||
|
return STATUS_NO_MEMORY;
|
||
|
}
|
||
|
|
||
|
*NewM = *m;
|
||
|
|
||
|
IntCb->IntHandler = Handler;
|
||
|
IntCb->IntMessage = NewM;
|
||
|
IntCb->IntContext = Context;
|
||
|
|
||
|
RtlEnterCriticalSection(&BlockLock);
|
||
|
|
||
|
p->IntControlBlock = IntCb;
|
||
|
|
||
|
if (ARGUMENT_PRESENT(BlockList)) {
|
||
|
InsertTailList(BlockList, &IntCb->Links);
|
||
|
} else {
|
||
|
InsertTailList(&DefaultBlockList, &IntCb->Links);
|
||
|
}
|
||
|
|
||
|
AcquireProcessLock(p);
|
||
|
|
||
|
//
|
||
|
// Check for signals
|
||
|
//
|
||
|
|
||
|
if (0 != (Sig = PsxCheckPendingSignals(p))) {
|
||
|
|
||
|
ReleaseProcessLock(p);
|
||
|
|
||
|
//
|
||
|
// Block is interrupted by a signal
|
||
|
//
|
||
|
|
||
|
if (ARGUMENT_PRESENT(CriticalSectionToRelease)) {
|
||
|
RtlLeaveCriticalSection(CriticalSectionToRelease);
|
||
|
}
|
||
|
UnblockProcess(p, SignalInterrupt, TRUE, Sig);
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
|
||
|
}
|
||
|
if (ARGUMENT_PRESENT(CriticalSectionToRelease)) {
|
||
|
RtlLeaveCriticalSection(CriticalSectionToRelease);
|
||
|
}
|
||
|
|
||
|
ReleaseProcessLock(p);
|
||
|
RtlLeaveCriticalSection(&BlockLock);
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOLEAN
|
||
|
UnblockProcess(
|
||
|
IN PPSX_PROCESS p,
|
||
|
IN PSX_INTERRUPTREASON InterruptReason,
|
||
|
IN BOOLEAN BlockLockHeld,
|
||
|
IN int Signal // Signal causing wakeup, if any
|
||
|
)
|
||
|
{
|
||
|
PINTCB IntCb;
|
||
|
if (!BlockLockHeld) {
|
||
|
RtlEnterCriticalSection(&BlockLock);
|
||
|
}
|
||
|
|
||
|
if (p->IntControlBlock) {
|
||
|
IntCb = p->IntControlBlock;
|
||
|
RemoveEntryList(&IntCb->Links);
|
||
|
p->IntControlBlock = (PINTCB) NULL;
|
||
|
(IntCb->IntHandler)(p,IntCb,InterruptReason,Signal);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if (!BlockLockHeld) {
|
||
|
RtlLeaveCriticalSection(&BlockLock);
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|