Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}