diff options
Diffstat (limited to 'src/ui_ipc.c')
-rw-r--r-- | src/ui_ipc.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/ui_ipc.c b/src/ui_ipc.c new file mode 100644 index 0000000..9eac79e --- /dev/null +++ b/src/ui_ipc.c @@ -0,0 +1,130 @@ +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#ifdef SEM_TIMEDWAIT +#include <time.h> +#endif +#include <semaphore.h> +#include <mqueue.h> +#include <sys/stat.h> +#include <errno.h> + +#include "ui_ipc.h" + +#define JMP_IF(cmd, retval, jmplabel) if ( (cmd) == retval ) { printf("(%s) == %p\n", #cmd, (void*)retval); goto jmplabel; } + + +static sem_t *sems[SEM_NUM]; +static mqd_t msqs[MSQ_NUM]; + + +int +ui_ipc_init(int is_master) +{ + volatile int sp_oflags, mq_oflags; + mode_t crt_flags; + struct mq_attr m_attr; + + bzero(sems, sizeof(sem_t*)*SEM_NUM); + bzero(msqs, sizeof(mqd_t)*MSQ_NUM); + m_attr.mq_flags = 0; + m_attr.mq_msgsize = IPC_MQSIZ; + m_attr.mq_maxmsg = 3; + m_attr.mq_curmsgs = 0; + if (is_master) { + sp_oflags = O_CREAT | O_EXCL; + mq_oflags = O_NONBLOCK | O_CREAT | O_EXCL; + crt_flags = S_IRUSR | S_IWUSR; + JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + } else { + sp_oflags = 0; + mq_oflags = 0; + crt_flags = 0; + JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + } + JMP_IF( sems[SEM_UI] = sem_open(SEM_GUI, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_IN] = sem_open(SEM_INP, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_BS] = sem_open(SEM_BSY, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_RD] = sem_open(SEM_RDY, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + return 0; +error: + return errno; +} + +void +ui_ipc_free(int is_master) +{ + int i; + + for (i = 0; i < SEM_NUM; i++) { + if (sems[i]) sem_close(sems[i]); + } + for (i = 0; i < MSQ_NUM; i++) { + if (msqs[i]) mq_close(msqs[i]); + } + if (is_master > 0) { + sem_unlink(SEM_BSY); + sem_unlink(SEM_GUI); + sem_unlink(SEM_INP); + sem_unlink(SEM_RDY); + mq_unlink(MSQ_PWD); + mq_unlink(MSQ_INF); + } +} + +int +ui_ipc_sempost(enum UI_IPC_SEM e_sp) +{ + return ( sem_post(sems[e_sp]) ); +} + +int +ui_ipc_semwait(enum UI_IPC_SEM e_sp) +{ + return ( sem_wait(sems[e_sp]) ); +} + +int +ui_ipc_semtrywait(enum UI_IPC_SEM e_sp) +{ + return ( sem_trywait(sems[e_sp]) ); +} + +int +ui_ipc_getvalue(enum UI_IPC_SEM e_sp) +{ + int sp_val = 0; + + if (sem_getvalue(sems[e_sp], &sp_val) != 0) { + return -1; + } + return sp_val; +} + +#ifdef SEM_TIMEDWAIT +int +ui_ipc_semtimedwait(enum UI_IPC_SEM e_sp, int timeout) +{ + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + return -1; + } + ts.tc_sec += timeout; + return ( sem_timedwait(sems[q_mq], &ts) ); +} +#endif + +int +ui_ipc_msgsend(enum UI_IPC_MSQ e_mq, const char *msg_ptr, size_t msg_len) +{ + return ( mq_send(msqs[e_mq], msg_ptr, msg_len, 0) ); +} + +ssize_t +ui_ipc_msgrecv(enum UI_IPC_MSQ e_mq, char *msg_ptr, size_t msg_len) +{ + return ( mq_receive(msqs[e_mq], msg_ptr, msg_len, NULL) ); +} + |