move POSIX spawn, exec and child tracking into posixsrv, keep process transactions alive across reconnects and preserve stable PIDs across image replacement, flesh out spawn with ordered file actions, process-group selection and signal inheritance, implement execve with bootstrap validation and rollback before retiring the old process, add vfork children that share the native process while keeping separate POSIX descriptor and signal state, replace local spawn bookkeeping with child reaping, nonblocking and process-group waits and orphan cleanup, add signal dispositions, per-thread masks, pending delivery, process/group signalling and alarms, translate native exceptions into POSIX signals and inherit masks when creating threads, make pipe waits interruptible and raise SIGPIPE for broken pipes, pass arguments and environment into main and add getenv/environ, add direct user APC notifications that can run without an alertable wait, add current-thread capabilities and resume-and-wait, let accepted IPC endpoints open restricted peer process capabilities and preserve caller security during spawn and exec, make process preparation reusable and improve DLL lookup across current, executable and fallback directories, move keyboard repeat into RSSRV so PS/2 and USB share one repeat policy, fix video presentation, report launch failure stages and status codes, mooaaar tests.
This commit is contained in:
1 parent
73abd6f90d
commit
899225f551
57 files changed
+8817
-1216
No files matched your search
+3248
-224
File diff suppressed because it is too large.
Load diff
@@ -8,6 +8,8 @@
|
||||
#define RSSRV_EVENT_MANUAL_RESET 1u
|
||||
#define RSSRV_INPUT_KEY_QUEUE_MASK (RSSRV_INPUT_KEY_QUEUE_SIZE - 1u)
|
||||
#define RSSRV_INPUT_MOUSE_QUEUE_MASK (RSSRV_INPUT_MOUSE_QUEUE_SIZE - 1u)
|
||||
#define RSSRV_INPUT_REPEAT_INITIAL_MS 400u
|
||||
#define RSSRV_INPUT_REPEAT_PERIOD_MS 33u
|
||||
|
||||
typedef struct RSSRV_INPUT_SESSION {
|
||||
RSSRV_INPUT_STATE* Input;
|
||||
@@ -87,6 +89,29 @@ static int RssrvInputKeyIsRepeatable(INPUT_KEY key) {
|
||||
}
|
||||
}
|
||||
|
||||
// Arms RSSRV's logical typematic timer for one repeatable key.
|
||||
static void RssrvInputStartRepeatLocked(RSSRV_INPUT_STATE* input, INPUT_KEY key) {
|
||||
if (!input || input->RepeatTimer == SYS_HANDLE_INVALID || !RssrvInputKeyIsRepeatable(key))
|
||||
return;
|
||||
input->RepeatKey = key;
|
||||
SYS_SET_TIMER_REQUEST request;
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.Size = sizeof(request);
|
||||
request.TimerHandle = input->RepeatTimer;
|
||||
request.Flags = SYS_TIMER_FLAG_NONE;
|
||||
request.DueTimeMilliseconds = RSSRV_INPUT_REPEAT_INITIAL_MS;
|
||||
request.PeriodMilliseconds = RSSRV_INPUT_REPEAT_PERIOD_MS;
|
||||
(void)SysSetTimer(&request);
|
||||
}
|
||||
|
||||
// Stops RSSRV typematic when the active repeat key is released.
|
||||
static void RssrvInputStopRepeatLocked(RSSRV_INPUT_STATE* input, INPUT_KEY key) {
|
||||
if (!input || input->RepeatKey != key) return;
|
||||
input->RepeatKey = INPUT_KEY_NONE;
|
||||
if (input->RepeatTimer != SYS_HANDLE_INVALID)
|
||||
(void)SysCancelTimer(input->RepeatTimer);
|
||||
}
|
||||
|
||||
// Applies modifier and lock-key state for one first make or final break.
|
||||
static void RssrvInputUpdateModifierLocked(RSSRV_INPUT_STATE* input, INPUT_KEY key, int pressed) {
|
||||
uint32_t bit = 0;
|
||||
@@ -172,14 +197,14 @@ static void RssrvInputApplyKey(RSSRV_INPUT_STATE* input, const INPUT_KEY_EVENT*
|
||||
input->Generation++;
|
||||
RssrvInputQueueKeyLocked(input, key, &routedRecord);
|
||||
routeRecord = 1;
|
||||
} else if (RssrvInputKeyIsRepeatable(key)) {
|
||||
// Hardware typematic make events remain useful until RSSRV grows its own repeat timer.
|
||||
RssrvInputQueueKeyLocked(input, key, &routedRecord);
|
||||
routeRecord = 1;
|
||||
RssrvInputStartRepeatLocked(input, key);
|
||||
}
|
||||
// Repeated hardware make events are intentionally ignored. RSSRV owns
|
||||
// logical typematic so PS/2 and USB input share one repeat policy.
|
||||
} else if (wasDown) {
|
||||
RssrvInputSetKeyDownLocked(input, key, 0);
|
||||
RssrvInputUpdateModifierLocked(input, key, 0);
|
||||
RssrvInputStopRepeatLocked(input, key);
|
||||
input->Generation++;
|
||||
}
|
||||
RssrvInputUnlock(input);
|
||||
@@ -190,6 +215,35 @@ static void RssrvInputApplyKey(RSSRV_INPUT_STATE* input, const INPUT_KEY_EVENT*
|
||||
}
|
||||
}
|
||||
|
||||
// Emits logical typematic records while the active repeat key remains down.
|
||||
static void RssrvInputRepeatThread(uintptr_t argument) {
|
||||
RSSRV_INPUT_STATE* input = (RSSRV_INPUT_STATE*)argument;
|
||||
RssrvSetCurrentThreadName("rssrv.input.repeat");
|
||||
if (!input || input->RepeatTimer == SYS_HANDLE_INVALID) SysExitThread(1);
|
||||
|
||||
for (;;) {
|
||||
KSTATUS status = SysWait(input->RepeatTimer, SYS_WAIT_FLAG_NONE);
|
||||
if (!KSUCCESS(status)) SysExitThread(2);
|
||||
|
||||
INPUT_KEY_RECORD routedRecord;
|
||||
memset(&routedRecord, 0, sizeof(routedRecord));
|
||||
int routeRecord = 0;
|
||||
if (KSUCCESS(RssrvInputLock(input))) {
|
||||
INPUT_KEY key = input->RepeatKey;
|
||||
if (RssrvInputKeyIsRepeatable(key) && RssrvInputKeyDownLocked(input, key)) {
|
||||
RssrvInputQueueKeyLocked(input, key, &routedRecord);
|
||||
routeRecord = 1;
|
||||
}
|
||||
RssrvInputUnlock(input);
|
||||
}
|
||||
|
||||
if (routeRecord) {
|
||||
RssrvSessionObserveKey(input->Session, &routedRecord);
|
||||
RssrvSessionRouteKey(input->Session, &routedRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Applies one normalized relative mouse event and lets Session 0 own cursor and target routing policy.
|
||||
static void RssrvInputApplyMouse(RSSRV_INPUT_STATE* input, const INPUT_MOUSE_EVENT* event) {
|
||||
if (!input || !event) return;
|
||||
@@ -506,7 +560,9 @@ KSTATUS RssrvInputInitialize(RSSRV_INPUT_STATE* input,
|
||||
input->Mutex = SYS_HANDLE_INVALID;
|
||||
input->KeyEvent = SYS_HANDLE_INVALID;
|
||||
input->MouseEvent = SYS_HANDLE_INVALID;
|
||||
input->RepeatTimer = SYS_HANDLE_INVALID;
|
||||
input->Listener = SYS_HANDLE_INVALID;
|
||||
input->RepeatKey = INPUT_KEY_NONE;
|
||||
|
||||
KSTATUS status = SysCreateMutex(&input->Mutex);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
@@ -514,6 +570,8 @@ KSTATUS RssrvInputInitialize(RSSRV_INPUT_STATE* input,
|
||||
if (!KSUCCESS(status)) return status;
|
||||
status = SysCreateEvent(RSSRV_EVENT_MANUAL_RESET, 0, &input->MouseEvent);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
status = SysCreateTimer(&input->RepeatTimer);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
status = RssrvSessionQueryDisplayBounds(session, &input->MouseWidth, &input->MouseHeight);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
@@ -554,6 +612,15 @@ KSTATUS RssrvInputStart(RSSRV_INPUT_STATE* input) {
|
||||
status = SysCreateThread(&create);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
memset(&create, 0, sizeof(create));
|
||||
create.Size = sizeof(create);
|
||||
create.Entry = (uintptr_t)RssrvInputRepeatThread;
|
||||
create.Argument = (uintptr_t)input;
|
||||
create.Priority = 1;
|
||||
create.Flags = SYS_CREATE_THREAD_FLAG_NONE;
|
||||
status = SysCreateThread(&create);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
memset(&create, 0, sizeof(create));
|
||||
create.Size = sizeof(create);
|
||||
create.Entry = (uintptr_t)RssrvInputListenerThread;
|
||||
|
||||
@@ -87,12 +87,14 @@ typedef struct RSSRV_INPUT_STATE {
|
||||
SYS_HANDLE Mutex;
|
||||
SYS_HANDLE KeyEvent;
|
||||
SYS_HANDLE MouseEvent;
|
||||
SYS_HANDLE RepeatTimer;
|
||||
SYS_HANDLE Listener;
|
||||
RSSRV_NAMESPACE* Namespace;
|
||||
RSSRV_SESSION_STATE* Session;
|
||||
|
||||
uint8_t KeyDown[NTL_INPUT_KEY_BYTES];
|
||||
uint32_t Modifiers;
|
||||
INPUT_KEY RepeatKey;
|
||||
uint64_t Generation;
|
||||
INPUT_KEY_RECORD KeyQueue[RSSRV_INPUT_KEY_QUEUE_SIZE];
|
||||
uint32_t KeyHead;
|
||||
|
||||
Reference in new issue
Block a user