static cs_error_t reply_receive ( struct ipc_instance *ipc_instance, void *res_msg, size_t res_len) { coroipc_response_header_t *response_header; cs_error_t res; retry_ipc_sem_wait: res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_RESPONSE, ipc_instance->fd); if (res != CS_OK) { if (res == CS_ERR_TRY_AGAIN) { priv_change_send (ipc_instance); goto retry_ipc_sem_wait; } else { return (res); } } response_header = (coroipc_response_header_t *)ipc_instance->response_buffer; if (response_header->error == CS_ERR_TRY_AGAIN) { return (CS_ERR_TRY_AGAIN); } memcpy (res_msg, ipc_instance->response_buffer, res_len); return (CS_OK); }
static cs_error_t reply_receive_in_buf ( struct ipc_instance *ipc_instance, void **res_msg) { #if _POSIX_THREAD_PROCESS_SHARED < 1 struct sembuf sop; #else struct timespec timeout; struct pollfd pfd; #endif int res; #if _POSIX_THREAD_PROCESS_SHARED > 0 retry_semwait: timeout.tv_sec = time(NULL) + IPC_SEMWAIT_TIMEOUT; timeout.tv_nsec = 0; res = sem_timedwait (&ipc_instance->control_buffer->sem1, &timeout); if (res == -1 && errno == ETIMEDOUT) { pfd.fd = ipc_instance->fd; pfd.events = 0; poll (&pfd, 1, 0); if (pfd.revents == POLLERR || pfd.revents == POLLHUP) { return (CS_ERR_LIBRARY); } goto retry_semwait; } if (res == -1 && errno == EINTR) { goto retry_semwait; } #else /* * Wait for semaphore #1 indicating a new message from server * to client in the response queue */ sop.sem_num = 1; sop.sem_op = -1; sop.sem_flg = 0; retry_semop: res = semop (ipc_instance->semid, &sop, 1); if (res == -1 && errno == EINTR) { return (CS_ERR_TRY_AGAIN); } else if (res == -1 && errno == EACCES) { priv_change_send (ipc_instance); goto retry_semop; } else if (res == -1) { return (CS_ERR_LIBRARY); } #endif *res_msg = (char *)ipc_instance->response_buffer; return (CS_OK); }
static cs_error_t msg_send ( struct ipc_instance *ipc_instance, const struct iovec *iov, unsigned int iov_len) { #if _POSIX_THREAD_PROCESS_SHARED < 1 struct sembuf sop; #endif int i; int res; int req_buffer_idx = 0; for (i = 0; i < iov_len; i++) { if ((req_buffer_idx + iov[i].iov_len) > ipc_instance->request_size) { return (CS_ERR_INVALID_PARAM); } memcpy (&ipc_instance->request_buffer[req_buffer_idx], iov[i].iov_base, iov[i].iov_len); req_buffer_idx += iov[i].iov_len; } #if _POSIX_THREAD_PROCESS_SHARED > 0 res = sem_post (&ipc_instance->control_buffer->sem0); if (res == -1) { return (CS_ERR_LIBRARY); } #else /* * Signal semaphore #0 indicting a new message from client * to server request queue */ sop.sem_num = 0; sop.sem_op = 1; sop.sem_flg = 0; retry_semop: res = semop (ipc_instance->semid, &sop, 1); if (res == -1 && errno == EINTR) { return (CS_ERR_TRY_AGAIN); } else if (res == -1 && errno == EACCES) { priv_change_send (ipc_instance); goto retry_semop; } else if (res == -1) { return (CS_ERR_LIBRARY); } #endif return (CS_OK); }
cs_error_t coroipcc_dispatch_put (hdb_handle_t handle) { coroipc_response_header_t *header; struct ipc_instance *ipc_instance; cs_error_t res; char *addr; unsigned int read_idx; res = hdb_error_to_cs (hdb_handle_get_always (&ipc_hdb, handle, (void **)&ipc_instance)); if (res != CS_OK) { return (res); } retry_ipc_sem_wait: res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_DISPATCH, ipc_instance->fd); if (res != CS_OK) { if (res == CS_ERR_TRY_AGAIN) { priv_change_send (ipc_instance); goto retry_ipc_sem_wait; } else { goto error_exit; } } addr = ipc_instance->dispatch_buffer; read_idx = ipc_instance->control_buffer->read; header = (coroipc_response_header_t *) &addr[read_idx]; ipc_instance->control_buffer->read = ((read_idx + header->size + 7) & 0xFFFFFFF8) % ipc_instance->dispatch_size; /* * Put from dispatch get and also from this call's get */ res = CS_OK; error_exit: hdb_handle_put (&ipc_hdb, handle); hdb_handle_put (&ipc_hdb, handle); return (res); }
static cs_error_t reply_receive_in_buf ( struct ipc_instance *ipc_instance, void **res_msg) { cs_error_t res; retry_ipc_sem_wait: res = ipc_sem_wait (ipc_instance->control_buffer, SEMAPHORE_RESPONSE, ipc_instance->fd); if (res != CS_OK) { if (res == CS_ERR_TRY_AGAIN) { priv_change_send (ipc_instance); goto retry_ipc_sem_wait; } else { return (res); } } *res_msg = (char *)ipc_instance->response_buffer; return (CS_OK); }
cs_error_t coroipcc_dispatch_put (hdb_handle_t handle) { #if _POSIX_THREAD_PROCESS_SHARED < 1 struct sembuf sop; #endif coroipc_response_header_t *header; struct ipc_instance *ipc_instance; int res; char *addr; unsigned int read_idx; res = hdb_error_to_cs (hdb_handle_get_always (&ipc_hdb, handle, (void **)&ipc_instance)); if (res != CS_OK) { return (res); } #if _POSIX_THREAD_PROCESS_SHARED > 0 retry_semwait: res = sem_wait (&ipc_instance->control_buffer->sem2); if (res == -1 && errno == EINTR) { goto retry_semwait; } #else sop.sem_num = 2; sop.sem_op = -1; sop.sem_flg = 0; retry_semop: res = semop (ipc_instance->semid, &sop, 1); if (res == -1 && errno == EINTR) { res = CS_ERR_TRY_AGAIN; goto error_exit; } else if (res == -1 && errno == EACCES) { priv_change_send (ipc_instance); goto retry_semop; } else if (res == -1) { res = CS_ERR_LIBRARY; goto error_exit; } #endif addr = ipc_instance->dispatch_buffer; read_idx = ipc_instance->control_buffer->read; header = (coroipc_response_header_t *) &addr[read_idx]; ipc_instance->control_buffer->read = (read_idx + header->size) % ipc_instance->dispatch_size; /* * Put from dispatch get and also from this call's get */ res = CS_OK; #if _POSIX_THREAD_PROCESS_SHARED < 1 error_exit: #endif hdb_handle_put (&ipc_hdb, handle); hdb_handle_put (&ipc_hdb, handle); return (res); }