Silent more debug prints and remove an unused DPRINT1 I've introduced in r57666.
svn path=/branches/ros-csrss/; revision=58104
DPRINT("Ctrl-Break Event\n");
break;
- case CTRL_SHUTDOWN_EVENT:
- DPRINT("Ctrl Shutdown Event\n");
- break;
-
case CTRL_CLOSE_EVENT:
DPRINT("Ctrl Close Event\n");
break;
case CTRL_LOGOFF_EVENT:
DPRINT("Ctrl Logoff Event\n");
break;
+
+ case CTRL_SHUTDOWN_EVENT:
+ DPRINT("Ctrl Shutdown Event\n");
+ break;
}
ExitProcess(CONTROL_C_EXIT);
#include <k32.h>
-// #define NDEBUG
+#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
/* Initialize Console Support */
if (!BasepInitConsole())
{
- DPRINT1("Failure to set up console\n");
+ DPRINT1("Failed to set up console\n");
return FALSE;
}
#include <k32.h>
-// #define NDEBUG
+#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
sizeof(BASE_CREATE_THREAD));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(ApiMessage.Status))
{
- DPRINT1("Failed to tell csrss about new thread: %lx %lx\n", Status, ApiMessage.Status);
+ DPRINT1("Failed to tell CSRSS about new thread: %lx %lx\n", Status, ApiMessage.Status);
return ApiMessage.Status;
}
}
/* Call CSR */
- DPRINT1("Calling CsrClientCallServer from BasepCreateFirstThread...\n");
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateProcess),
sizeof(BASE_CREATE_PROCESS));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(ApiMessage.Status))
{
- DPRINT1("Failed to tell csrss about new process: %lx %lx\n", Status, ApiMessage.Status);
+ DPRINT1("Failed to tell CSRSS about new process: %lx %lx\n", Status, ApiMessage.Status);
return NULL;
}
return FALSE;
}
- /* Get the data out of the LCP reply */
+ /* Get the data back */
*lpdwLevel = GetShutdownParametersRequest->Level;
*lpdwFlags = GetShutdownParametersRequest->Flags;
return TRUE;
InsertTailList(&Console->InputEvents, &ConInRec->ListEntry);
SetEvent(Console->ActiveEvent);
+/*
+ if (CsrNotifyWait(&Console->ReadWaitQueue,
+ WaitAny,
+ NULL,
+ NULL))
+ {
+ ASSERT(Console->SatisfiedWaits == NULL);
+ Console->SatisfiedWaits = &Console->ReadWaitQueue;
+ }
+*/
CsrNotifyWait(&Console->ReadWaitQueue,
WaitAny,
NULL,
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
current_entry = current_entry->Flink;
- ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
+ ConioConsoleCtrlEvent(CTRL_C_EVENT, current);
}
if (Console->LineBuffer && !Console->LineComplete)
{
CapturedInputInfo,
NULL))
{
+ /* Fail */
HeapFree(ConSrvHeap, 0, CapturedInputInfo);
return STATUS_NO_MEMORY;
}
PCSRSS_GET_CONSOLE_INPUT GetConsoleInputRequest = &((PCONSOLE_API_MESSAGE)WaitApiMessage)->Data.GetConsoleInputRequest;
PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
+ DWORD Flag = (DWORD)WaitArgument1;
+ BOOLEAN InputHandleClosing = (WaitArgument2 == (PVOID)0xdeaddead);
+
+ DPRINT("ReadInputBufferThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
+
+ /*
+ * If we are signaled by pressing Ctrl-C or Ctrl-Break,
+ * just ignore this event.
+ */
+ if ( (Flag == 1 << CTRL_C_EVENT) ||
+ (Flag == 1 << CTRL_BREAK_EVENT) )
+ {
+ return FALSE;
+ }
+
+ /*
+ * If we are called via CsrNotifyWaitBlock by a call to
+ * CsrDestroyProcess or CsrDestroyThread, just return.
+ */
+ if (WaitFlags & CsrProcessTerminating)
+ {
+ Status = STATUS_THREAD_IS_TERMINATING;
+ goto Quit;
+ }
+
+ /*
+ * If we are about to close an input handle, then just return.
+ */
+ if (InputHandleClosing)
+ {
+ Status = STATUS_ALERTED;
+ goto Quit;
+ }
+
Status = ReadInputBuffer(InputInfo,
GetConsoleInputRequest->bRead,
WaitApiMessage,
FALSE);
+Quit:
if (Status != STATUS_PENDING)
{
WaitApiMessage->Status = Status;
NTSTATUS Status;
PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext;
+ DWORD Flag = (DWORD)WaitArgument1;
+ BOOLEAN InputHandleClosing = (WaitArgument2 == (PVOID)0xdeaddead);
+
+ DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
+
+ /*
+ * If we are called via CsrNotifyWaitBlock by a call to
+ * CsrDestroyProcess or CsrDestroyThread, just return.
+ */
+ if (WaitFlags & CsrProcessTerminating)
+ {
+ Status = STATUS_THREAD_IS_TERMINATING;
+ goto Quit;
+ }
+
+ /*
+ * If we are signaled by pressing Ctrl-C or Ctrl-Break,
+ * or that we close an input handle, then just return.
+ */
+ if ( (Flag == 1 << CTRL_C_EVENT) ||
+ (Flag == 1 << CTRL_BREAK_EVENT) ||
+ (InputHandleClosing == TRUE) )
+ {
+ Status = STATUS_ALERTED;
+ goto Quit;
+ }
+
Status = ReadChars(InputInfo,
WaitApiMessage,
FALSE);
+Quit:
if (Status != STATUS_PENDING)
{
WaitApiMessage->Status = Status;
/* We haven't read anything (yet) */
+ // Cooked-like mode
if (InputInfo->Console->Mode & ENABLE_LINE_INPUT)
{
if (InputInfo->Console->LineBuffer == NULL)
WaitForMoreToRead = FALSE;
}
}
- else
+ else // Raw-like mode
{
/* Character input */
while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead &&
typedef struct tagCSRSS_SCREEN_BUFFER
{
Object_t Header; /* Object header */
- BYTE *Buffer; /* pointer to screen buffer */
- USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
- USHORT ShowX, ShowY; /* beginning offset for the actual display area */
+ LIST_ENTRY ListEntry; /* Entry in console's list of buffers */
+
+ BYTE *Buffer; /* Pointer to screen buffer */
+ USHORT MaxX, MaxY; /* Size of the entire scrollback buffer */
+ USHORT ShowX, ShowY; /* Beginning offset for the actual display area */
ULONG CurrentX; /* Current X cursor position */
ULONG CurrentY; /* Current Y cursor position */
- WORD DefaultAttrib; /* default char attribute */
- USHORT VirtualY; /* top row of buffer being displayed, reported to callers */
+ WORD DefaultAttrib; /* Default char attribute */
+ USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
CONSOLE_CURSOR_INFO CursorInfo;
USHORT Mode;
- LIST_ENTRY ListEntry; /* entry in console's list of buffers */
} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
typedef struct tagCSRSS_CONSOLE
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
+#if 0
+ /* Pointers to lists of wait blocks, when they contain satisfied waits to be freed */
+ PLIST_ENTRY SatisfiedWaits;
+
+ /* Pointers to lists of wait blocks, when they contain satisfied waits to be freed */
+ PLIST_ENTRY ReadSatisfiedWaits;
+ PLIST_ENTRY WriteSatisfiedWaits;
+#endif
+
WORD Mode; /* Console mode flags */
UNICODE_STRING Title; /* Title of console */
DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */
{
NTSTATUS Status;
+ DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags);
+
+ /*
+ * If we are called via CsrNotifyWaitBlock by a call to
+ * CsrDestroyProcess or CsrDestroyThread, just return.
+ */
+ if (WaitFlags & CsrProcessTerminating)
+ {
+ Status = STATUS_THREAD_IS_TERMINATING;
+ goto Quit;
+ }
+
Status = DoWriteConsole(WaitApiMessage,
WaitThread,
FALSE);
+Quit:
if (Status != STATUS_PENDING)
{
WaitApiMessage->Status = Status;
DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
+ /* Notify all the waits only if we see Ctrl-C or Ctrl-Break */
+ if (Event == CTRL_C_EVENT || Event == CTRL_BREAK_EVENT)
+ {
+ DWORD Flag = (1 << Event); // Transform an integer value to a power of 2.
+ NTSTATUS Status;
+ PCSRSS_CONSOLE Console;
+ // LIST_ENTRY WaitQueue;
+
+ DPRINT1("ConioConsoleCtrlEvent - Ctrl-C captured\n");
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT1("ConioConsoleCtrlEvent - console captured, try to dereference waits...\n");
+ /*
+ * Wake-up all of the writing waiters, dereference them
+ * and purge them all from the list.
+ */
+ if (CsrNotifyWait(&Console->ReadWaitQueue,
+ WaitAll,
+ (PVOID)Flag,
+ NULL))
+ {
+ DPRINT1("ConioConsoleCtrlEvent - waits dereferenced...\n");
+ // InitializeListHead(&WaitQueue);
+
+ // CsrMoveSatisfiedWait(&WaitQueue, &Console->ReadWaitQueue);
+ if (!IsListEmpty(&Console->ReadWaitQueue /* &WaitQueue */))
+ {
+ CsrDereferenceWait(&Console->ReadWaitQueue /* &WaitQueue */);
+ }
+ }
+ ConioUnlockConsole(Console); // NOTE_WAITS: <-- Here we have the possibility to free the console waits also.
+ }
+ }
+
+ /* Notify the process of the control event */
if (ProcessData->CtrlDispatcher)
{
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
InitializeListHead(&Console->ProcessList);
InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL;
+ // Console->SatisfiedWaits = NULL;
InitializeListHead(&Console->ReadWaitQueue);
InitializeListHead(&Console->WriteWaitQueue);
InitializeListHead(&Console->InputEvents);
DPRINT("ConioDeleteConsole\n");
+ /* TODO: Dereference all the waits in Console->ReadWaitQueue */
+ /* TODO: Dereference all the waits in Console->WriteWaitQueue */
+
/* Drain input event queue */
while (Console->InputEvents.Flink != &Console->InputEvents)
{
VOID FASTCALL
ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
{
+ // LIST_ENTRY WaitQueue;
+
Console->PauseFlags &= ~Flags;
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
- CsrNotifyWait(&Console->WriteWaitQueue,
- WaitAll,
- NULL,
- NULL);
+ /*
+ * Wake-up all of the writing waiters, dereference them
+ * and purge them all from the list.
+ */
+ if (CsrNotifyWait(&Console->WriteWaitQueue,
+ WaitAll,
+ NULL,
+ NULL))
+ {
+ // InitializeListHead(&WaitQueue);
+
+ // CsrMoveSatisfiedWait(&WaitQueue, &Console->WriteWaitQueue);
+ if (!IsListEmpty(&Console->WriteWaitQueue /* &WaitQueue */))
+ {
+ CsrDereferenceWait(&Console->WriteWaitQueue /* &WaitQueue */);
+ }
+ }
}
}
#include "consrv.h"
#include "conio.h"
-//#define NDEBUG
+#define NDEBUG
#include <debug.h>
Win32CsrCloseHandleEntry(PCSRSS_HANDLE Entry)
{
Object_t *Object = Entry->Object;
+
if (Object != NULL)
{
PCSRSS_CONSOLE Console = Object->Console;
EnterCriticalSection(&Console->Lock);
+ if (Object->Type == CONIO_CONSOLE_MAGIC)
+ {
+ // LIST_ENTRY WaitQueue;
+
+ /*
+ * Wake-up all of the writing waiters if any, dereference them
+ * and purge them all from the list.
+ */
+ CsrNotifyWait(&Console->ReadWaitQueue,
+ WaitAll,
+ NULL,
+ (PVOID)0xdeaddead);
+ // InitializeListHead(&WaitQueue);
+
+ // CsrMoveSatisfiedWait(&WaitQueue, &Console->ReadWaitQueue);
+ if (!IsListEmpty(&Console->ReadWaitQueue /* &WaitQueue */))
+ {
+ CsrDereferenceWait(&Console->ReadWaitQueue /* &WaitQueue */);
+ }
+ }
+
/* If the last handle to a screen buffer is closed, delete it... */
if (AdjustHandleCounts(Entry, -1) == 0)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
-
- DPRINT1("Win32CsrReleaseObject - Process 0x%p, Release 0x%p\n", ProcessData->Process, &ProcessData->HandleTable[h]);
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
{
LeaveCriticalSection(&Console->Lock);
+#if 0
+ /* If it was the last held lock for the owning thread... */
+ if (&Console->Lock.RecursionCount == 0)
+ {
+ /* ...dereference waiting threads if any */
+ LIST_ENTRY WaitQueue;
+ InitializeListHead(&WaitQueue);
+
+ CsrMoveSatisfiedWait(&WaitQueue, Console->SatisfiedWaits);
+ Console->SatisfiedWaits = NULL;
+ if (!IsListEmpty(&WaitQueue))
+ {
+ CsrDereferenceWait(&WaitQueue);
+ }
+ }
+#endif
+
/* Decrement reference count */
if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
ConioDeleteConsole(Console);