summaryrefslogtreecommitdiff
path: root/src/kernel/ipc/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/ipc/object.c')
-rw-r--r--src/kernel/ipc/object.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c
new file mode 100644
index 0000000..70c31b2
--- /dev/null
+++ b/src/kernel/ipc/object.c
@@ -0,0 +1,113 @@
+#include "object.h"
+#include <lib/mutex.h>
+#include <mem/mem.h>
+
+struct object* obj_new(struct process* owner) {
+ struct object* ret = kmalloc(sizeof(struct object));
+ ret->owner = owner;
+ ret->descriptors = 0;
+ ret->busyMutex = MUTEX_UNLOCKED;
+ ret->request = 0;
+ return ret;
+}
+
+void obj_delete(struct object* obj) {
+ if (obj->descriptors > 0) return;
+ if (obj->busyMutex != MUTEX_UNLOCKED) return;
+ if (obj->request != 0) return;
+ kfree(obj);
+}
+
+int obj_createP(struct process* p) {
+ return objdesc_add(p, obj_new(p));
+}
+
+void obj_closeP(struct process* p, int id) {
+ struct object* obj = objdesc_read(p, id);
+ if (obj == 0) return;
+ objdesc_rm(p, id);
+ if (obj->owner == p) {
+ if (obj->descriptors > 0) {
+ obj->owner = 0; // set object to be invalid
+ //if a request was being handled, give it a null response
+ } else {
+ obj_delete(obj);
+ }
+ } else {
+ if (obj->descriptors == 0 && obj->owner == 0) {
+ obj_delete(obj);
+ }
+ //future : send message becuz object was closed
+ }
+}
+
+void obj_closeall(struct process* p) {
+ while (p->objects != 0) obj_closeP(p, p->objects->id);
+}
+
+// DESCRIPTORS
+
+int objdesc_add(struct process* proc, struct object* obj) {
+ struct obj_descriptor *ret = kmalloc(sizeof(struct obj_descriptor));
+ ret->obj = obj;
+ ret->id = proc->next_objdesc;
+ ret->next = proc->objects;
+ proc->objects = ret;
+ obj->descriptors++;
+ proc->next_objdesc++;
+ return ret->id;
+}
+
+int objdesc_get(struct process* proc, struct object* obj) {
+ struct obj_descriptor *it = proc->objects;
+ while (it != 0) {
+ if (it->obj == obj) return it->id;
+ it = it->next;
+ }
+ return -1;
+}
+
+struct object* objdesc_read(struct process* proc, int id) {
+ struct obj_descriptor *it = proc->objects;
+ while (it != 0) {
+ if (it->id == id) return it->obj;
+ it = it->next;
+ }
+ return 0;
+}
+
+void objdesc_rm(struct process* proc, int id) {
+ struct obj_descriptor *e = proc->objects;
+ if (e != 0 && e->id == id) {
+ proc->objects = e->next;
+ e->obj->descriptors--;
+ kfree(e);
+ return;
+ }
+ while (e->next != 0) {
+ if (e->next->id == id) {
+ e->next = e->next->next;
+ e->next->obj->descriptors--;
+ kfree(e->next);
+ return;
+ }
+ e = e->next;
+ }
+}
+
+// SYSCALLS
+
+int object_create() {
+ return obj_createP(current_thread->process);
+}
+
+int object_owned(int id) {
+ struct object *obj = objdesc_read(current_thread->process, id);
+ if (obj == 0) return -1;
+ if (obj->owner == current_thread->process) return 1;
+ return 0;
+}
+
+void object_close(int id) {
+ obj_closeP(current_thread->process, id);
+}