windows-nt/Source/XPSP1/NT/base/subsys/posix/psxss/procblk.c

126 lines
2.2 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}