From 03d77c9774110a1ce62dcb61842cea876a693a45 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 18 Nov 2022 05:09:25 +0200 Subject: [PATCH] IPC implementation --- Tasking/InterProcessCommunication.cpp | 102 +++++++++++++++++++++++--- include/ipc.hpp | 25 ++++--- 2 files changed, 106 insertions(+), 21 deletions(-) diff --git a/Tasking/InterProcessCommunication.cpp b/Tasking/InterProcessCommunication.cpp index 5ccabcc..4a94acd 100644 --- a/Tasking/InterProcessCommunication.cpp +++ b/Tasking/InterProcessCommunication.cpp @@ -1,13 +1,19 @@ #include +#include +#include + #include "../kernel.h" +NewLock(IPCLock); + InterProcessCommunication::IPC *ipc = nullptr; namespace InterProcessCommunication { IPCHandle *IPC::RegisterHandle(IPCPort Port) { + SmartLock(IPCLock); if (Port == 0) return nullptr; @@ -20,26 +26,104 @@ namespace InterProcessCommunication handle->ID = -1; handle->Buffer = nullptr; handle->Length = 0; - handle->Type = IPCOperationNone; + handle->Operation = IPCOperationNone; handle->Listening = 0; handle->Error = IPCUnknown; pcb->IPCHandles->AddNode(Port, (uint64_t)handle); return handle; } - IPCHandle *IPC::Wait(IPCPort port) + IPCError IPC::Listen(IPCPort Port) { - return nullptr; + SmartLock(IPCLock); + if (Port == 0) + return IPCError{IPCInvalidPort}; + + Tasking::PCB *pcb = TaskManager->GetCurrentProcess(); + + if (pcb->IPCHandles->Get((int)Port) == 0) + return IPCError{IPCPortNotRegistered}; + + IPCHandle *handle = (IPCHandle *)pcb->IPCHandles->Get((int)Port); + handle->Listening = 1; + return IPCError{IPCSuccess}; } - IPCError IPC::Read(int PID, IPCPort port, void *buf, int size) + IPCHandle *IPC::Wait(IPCPort Port) { - return IPCError{IPCUnknown}; + SmartLock(IPCLock); + if (Port == 0) + return nullptr; + + Tasking::PCB *pcb = TaskManager->GetCurrentProcess(); + + if (pcb->IPCHandles->Get((int)Port) == 0) + return nullptr; + + IPCHandle *handle = (IPCHandle *)pcb->IPCHandles->Get((int)Port); + + while (handle->Listening == 1) + CPU::Pause(); + + return handle; } - IPCError IPC::Write(int PID, IPCPort port, void *buf, int size) + IPCError IPC::Read(Tasking::UPID ID, IPCPort Port, uint8_t *&Buffer, long &Size) { - return IPCError{IPCUnknown}; + SmartLock(IPCLock); + if (Port == 0) + return IPCError{IPCInvalidPort}; + + Tasking::PCB *pcb = TaskManager->GetCurrentProcess(); + + if (pcb->IPCHandles->Get((int)Port) == 0) + return IPCError{IPCInvalidPort}; + + IPCHandle *handle = (IPCHandle *)pcb->IPCHandles->Get((int)Port); + + if (handle->Listening == 0) + return IPCError{IPCPortInUse}; + + Buffer = handle->Buffer; + Size = handle->Length; + handle->Operation = IPCOperationRead; + handle->Listening = 1; + handle->Error = IPCSuccess; + + return IPCError{IPCSuccess}; + } + + IPCError IPC::Write(Tasking::UPID ID, IPCPort Port, uint8_t *Buffer, long Size) + { + SmartLock(IPCLock); + if (Port == 0) + return IPCError{IPCInvalidPort}; + + Vector Processes = TaskManager->GetProcessList(); + + for (uint64_t i = 0; i < Processes.size(); i++) + { + Tasking::PCB *pcb = Processes[i]; + + if (pcb->ID == ID) + { + if (pcb->IPCHandles->Get((int)Port) == 0) + return IPCError{IPCInvalidPort}; + + IPCHandle *handle = (IPCHandle *)pcb->IPCHandles->Get((int)Port); + + if (handle->Listening == 0) + return IPCError{IPCNotListening}; + + handle->Buffer = Buffer; + handle->Length = Size; + handle->Operation = IPCOperationWrite; + handle->Listening = 0; + handle->Error = IPCSuccess; + } + } + + return IPCError{IPCIDNotFound}; } void IPCServiceStub() @@ -47,12 +131,12 @@ namespace InterProcessCommunication trace("IPC Service Started."); TaskManager->GetCurrentThread()->SetPriority(1); // TODO: do something useful here, like, IPC event viewer or smth... - while (1) - ; + CPU::Pause(true); } IPC::IPC() { + SmartLock(IPCLock); trace("Starting IPC Service..."); Vector auxv; Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv); diff --git a/include/ipc.hpp b/include/ipc.hpp index 9757319..ca74896 100644 --- a/include/ipc.hpp +++ b/include/ipc.hpp @@ -7,7 +7,7 @@ namespace InterProcessCommunication { - typedef unsigned int IPCPort; + typedef int IPCPort; enum IPCOperationType { @@ -24,16 +24,17 @@ namespace InterProcessCommunication IPCTimeout, IPCInvalidPort, IPCPortInUse, - IPCPortNotRegistered + IPCPortNotRegistered, + IPCIDNotFound }; typedef struct { int ID; - int Length; - void *Buffer; + long Length; + uint8_t *Buffer; bool Listening; - IPCOperationType Type; + IPCOperationType Operation; IPCErrorCode Error; LockClass Lock; } IPCHandle; @@ -41,10 +42,10 @@ namespace InterProcessCommunication typedef struct { int ID; - int Length; - IPCOperationType Type; + long Length; + IPCOperationType Operation; IPCErrorCode Error; - void *Buffer; + uint8_t *Buffer; // Reserved IPCHandle *HandleBuffer; @@ -58,15 +59,15 @@ namespace InterProcessCommunication class IPC { private: - public: IPC(); ~IPC(); IPCHandle *RegisterHandle(IPCPort Port); - IPCHandle *Wait(IPCPort port); - IPCError Read(int pid, IPCPort port, void *buf, int size); - IPCError Write(int pid, IPCPort port, void *buf, int size); + IPCError Listen(IPCPort Port); + IPCHandle *Wait(IPCPort Port); + IPCError Read(unsigned long /* Tasking::UPID */ ID, IPCPort Port, uint8_t *&Buffer, long &Size); + IPCError Write(unsigned long /* Tasking::UPID */ ID, IPCPort Port, uint8_t *Buffer, long Size); }; }