#include "ipc.h" #include "api/error.h" #include "proc/process.h" #include "sys/objdir.h" #include "jove.h" inline pid_t port_get_owner(struct port *port) { return port->owner; } inline struct port *port_get_send_target(struct port *port) { return port->send_target; } inline struct port *port_get_recv_target(struct port *port) { return port->recv_target; } inline void port_set_recv_target(struct port *port, struct port *target) { port->recv_target = target; } inline bool port_poll_send(struct port *port) { return port_get_send_target(port) != 0; } inline bool port_poll_recv(struct port *port) { return obj_peektype(port->recv) != JOVE_OBJ_NONE; } int port_take_send(struct port *port, jove_owned_obj_t *dest_obj) { jove_owned_obj_t *send_obj = obj_take(&port->send); if(!port_get_send_target(port)) { ipc_klogf("Port %p does not have mail to send\n", port); obj_release(send_obj); return -EEMPTY; } ipc_klogf("Taking obj from %i into obj %p\n", port->send_target, dest_obj); objdir_swapobj(send_obj, dest_obj); port->send_target = 0; obj_release(send_obj); return 0; } struct port *port_take_recv(struct port *port, jove_owned_obj_t *dest_obj) { errno = 0; jove_owned_obj_t *recv_obj = obj_take(&port->recv); //Validate that the port has an object in the recv object. if(obj_gettype(recv_obj) == JOVE_OBJ_NONE) { ipc_klogf("Port %p does not have mail\n", port); obj_release(recv_obj); errno = EEMPTY; return NULL; } ipc_klogf("Taking obj from %i into obj %p\n", port->recv_target, dest_obj); objdir_swapobj(recv_obj, dest_obj); struct port *recv_port = port_get_recv_target(port); port_set_recv_target(port, (void*)-1); obj_release(recv_obj); return recv_port; } int port_send(struct port *source, struct port *target, jove_owned_obj_t *sent_obj) { jove_owned_obj_t *target_recv_obj = obj_take(&target->recv); //Validate that the target is full or is not accepting from this port. if((port_get_recv_target(target) != 0 && port_get_recv_target(target) != source) || port_poll_recv(target)) { obj_release(target_recv_obj); ipc_klogf("Target %p is full. Sending to send buffer. \n", target); jove_owned_obj_t *source_send_obj = obj_take(&source->send); //Validate that the send buffer has space. if(port_get_send_target(source)) { ipc_klogf("Source %p is full\n", source); obj_release(source_send_obj); return -EFULL; } objdir_swapobj(source_send_obj, sent_obj); source->send_target = target; obj_release(source_send_obj); return 1; } objdir_swapobj(target_recv_obj, sent_obj); target->recv_target = source; obj_release(target_recv_obj); return 0; } int port_recv(struct port *source, struct port *target) { jove_owned_obj_t *source_send_obj = obj_take(&source->send); jove_owned_obj_t *target_recv_obj = obj_take(&target->recv); objdir_swapobj(source_send_obj, target_recv_obj); target->recv_target = source; source->send_target = NULL; obj_release(target_recv_obj); obj_release(source_send_obj); return 0; }