IPC implementation

This commit is contained in:
Alex 2022-11-18 05:09:25 +02:00
parent 666991265f
commit 03d77c9774
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 106 additions and 21 deletions

View File

@ -1,13 +1,19 @@
#include <ipc.hpp> #include <ipc.hpp>
#include <lock.hpp>
#include <task.hpp>
#include "../kernel.h" #include "../kernel.h"
NewLock(IPCLock);
InterProcessCommunication::IPC *ipc = nullptr; InterProcessCommunication::IPC *ipc = nullptr;
namespace InterProcessCommunication namespace InterProcessCommunication
{ {
IPCHandle *IPC::RegisterHandle(IPCPort Port) IPCHandle *IPC::RegisterHandle(IPCPort Port)
{ {
SmartLock(IPCLock);
if (Port == 0) if (Port == 0)
return nullptr; return nullptr;
@ -20,26 +26,104 @@ namespace InterProcessCommunication
handle->ID = -1; handle->ID = -1;
handle->Buffer = nullptr; handle->Buffer = nullptr;
handle->Length = 0; handle->Length = 0;
handle->Type = IPCOperationNone; handle->Operation = IPCOperationNone;
handle->Listening = 0; handle->Listening = 0;
handle->Error = IPCUnknown; handle->Error = IPCUnknown;
pcb->IPCHandles->AddNode(Port, (uint64_t)handle); pcb->IPCHandles->AddNode(Port, (uint64_t)handle);
return 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<Tasking::PCB *> 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() void IPCServiceStub()
@ -47,12 +131,12 @@ namespace InterProcessCommunication
trace("IPC Service Started."); trace("IPC Service Started.");
TaskManager->GetCurrentThread()->SetPriority(1); TaskManager->GetCurrentThread()->SetPriority(1);
// TODO: do something useful here, like, IPC event viewer or smth... // TODO: do something useful here, like, IPC event viewer or smth...
while (1) CPU::Pause(true);
;
} }
IPC::IPC() IPC::IPC()
{ {
SmartLock(IPCLock);
trace("Starting IPC Service..."); trace("Starting IPC Service...");
Vector<AuxiliaryVector> auxv; Vector<AuxiliaryVector> auxv;
Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv); Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv);

View File

@ -7,7 +7,7 @@
namespace InterProcessCommunication namespace InterProcessCommunication
{ {
typedef unsigned int IPCPort; typedef int IPCPort;
enum IPCOperationType enum IPCOperationType
{ {
@ -24,16 +24,17 @@ namespace InterProcessCommunication
IPCTimeout, IPCTimeout,
IPCInvalidPort, IPCInvalidPort,
IPCPortInUse, IPCPortInUse,
IPCPortNotRegistered IPCPortNotRegistered,
IPCIDNotFound
}; };
typedef struct typedef struct
{ {
int ID; int ID;
int Length; long Length;
void *Buffer; uint8_t *Buffer;
bool Listening; bool Listening;
IPCOperationType Type; IPCOperationType Operation;
IPCErrorCode Error; IPCErrorCode Error;
LockClass Lock; LockClass Lock;
} IPCHandle; } IPCHandle;
@ -41,10 +42,10 @@ namespace InterProcessCommunication
typedef struct typedef struct
{ {
int ID; int ID;
int Length; long Length;
IPCOperationType Type; IPCOperationType Operation;
IPCErrorCode Error; IPCErrorCode Error;
void *Buffer; uint8_t *Buffer;
// Reserved // Reserved
IPCHandle *HandleBuffer; IPCHandle *HandleBuffer;
@ -58,15 +59,15 @@ namespace InterProcessCommunication
class IPC class IPC
{ {
private: private:
public: public:
IPC(); IPC();
~IPC(); ~IPC();
IPCHandle *RegisterHandle(IPCPort Port); IPCHandle *RegisterHandle(IPCPort Port);
IPCHandle *Wait(IPCPort port); IPCError Listen(IPCPort Port);
IPCError Read(int pid, IPCPort port, void *buf, int size); IPCHandle *Wait(IPCPort Port);
IPCError Write(int pid, IPCPort port, void *buf, int size); 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);
}; };
} }