예제 #1
0
파일: ipcs.c 프로젝트: ip1981/libqb
void
qb_ipcs_connection_unref(struct qb_ipcs_connection *c)
{
	int32_t free_it;

	if (c == NULL) {
		return;
	}
	if (c->refcount < 1) {
		qb_util_log(LOG_ERR, "ref:%d state:%d fd:%d",
			    c->refcount, c->state,
			    c->setup.u.us.sock);
		assert(0);
	}
	free_it = qb_atomic_int_dec_and_test(&c->refcount);
	if (free_it) {
		qb_list_del(&c->list);
		if (c->service->serv_fns.connection_destroyed) {
			c->service->serv_fns.connection_destroyed(c);
		}
		c->service->funcs.disconnect(c);
		free(c->receive_buf);
		free(c);
	}
}
예제 #2
0
void
qb_rb_close(struct qb_ringbuffer_s * rb)
{
	if (rb == NULL) {
		return;
	}
	qb_enter();

	(void)qb_atomic_int_dec_and_test(&rb->shared_hdr->ref_count);
	(void)qb_rb_close_helper(rb, rb->flags & QB_RB_FLAG_CREATE, QB_FALSE);
}
예제 #3
0
파일: ringbuffer.c 프로젝트: ip1981/libqb
void
qb_rb_close(struct qb_ringbuffer_s * rb)
{
	if (rb == NULL) {
		return;
	}

	(void)qb_atomic_int_dec_and_test(&rb->shared_hdr->ref_count);
	if (rb->flags & QB_RB_FLAG_CREATE) {
		(void)rb->sem_destroy_fn(rb);
		unlink(rb->shared_hdr->data_path);
		unlink(rb->shared_hdr->hdr_path);
		qb_util_log(LOG_DEBUG,
			    "Free'ing ringbuffer: %s",
			    rb->shared_hdr->hdr_path);
	} else {
		qb_util_log(LOG_DEBUG,
			    "Closing ringbuffer: %s", rb->shared_hdr->hdr_path);
	}
	munmap(rb->shared_data, (rb->shared_hdr->word_size * sizeof(uint32_t)) << 1);
	munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s));
	free(rb);
}
예제 #4
0
파일: ipcs.c 프로젝트: ip1981/libqb
void
qb_ipcs_unref(struct qb_ipcs_service *s)
{
	int32_t free_it;
	struct qb_ipcs_connection *c = NULL;
	struct qb_list_head *pos;
	struct qb_list_head *n;

	assert(s->ref_count > 0);
	free_it = qb_atomic_int_dec_and_test(&s->ref_count);
	if (free_it) {
		qb_util_log(LOG_DEBUG, "%s() - destroying", __func__);
		for (pos = s->connections.next, n = pos->next;
		     pos != &s->connections; pos = n, n = pos->next) {
			c = qb_list_entry(pos, struct qb_ipcs_connection, list);
			if (c == NULL) {
				continue;
			}
			qb_ipcs_disconnect(c);
		}
		(void)qb_ipcs_us_withdraw(s);
		free(s);
	}
}
예제 #5
0
파일: ipc_socket.c 프로젝트: fjrti/libqb
/*
 * recv a message of unknown size.
 */
static ssize_t
qb_ipc_us_recv_at_most(struct qb_ipc_one_way *one_way,
		       void *msg, size_t len, int32_t timeout)
{
	int32_t result;
	int32_t final_rc = 0;
	int32_t to_recv = 0;
	char *data = msg;
	struct ipc_us_control *ctl = NULL;
	int32_t time_waited = 0;
	int32_t time_to_wait = timeout;

	if (timeout == -1) {
		time_to_wait = 1000;
	}

	qb_sigpipe_ctl(QB_SIGPIPE_IGNORE);

retry_peek:
	result = recv(one_way->u.us.sock, data,
		      sizeof(struct qb_ipc_request_header),
		      MSG_NOSIGNAL | MSG_PEEK);

	if (result == -1) {
		if (errno == EAGAIN && (time_waited < timeout || timeout == -1)) {
			result = qb_ipc_us_ready(one_way, NULL,
						 time_to_wait, POLLIN);
			time_waited += time_to_wait;
			goto retry_peek;
		} else {
			return -errno;
		}
	}
	if (result >= sizeof(struct qb_ipc_request_header)) {
		struct qb_ipc_request_header *hdr = NULL;
		hdr = (struct qb_ipc_request_header *)msg;
		to_recv = hdr->size;
	}

	result = recv(one_way->u.us.sock, data, to_recv,
		      MSG_NOSIGNAL | MSG_WAITALL);
	if (result == -1) {
		final_rc = -errno;
		goto cleanup_sigpipe;
	} else if (result == 0) {
		qb_util_log(LOG_DEBUG, "recv == 0 -> ENOTCONN");

		final_rc = -ENOTCONN;
		goto cleanup_sigpipe;
	}

	final_rc = result;

	ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
	if (ctl) {
		(void)qb_atomic_int_dec_and_test(&ctl->sent);
	}

cleanup_sigpipe:
	qb_sigpipe_ctl(QB_SIGPIPE_DEFAULT);
	return final_rc;
}
예제 #6
0
파일: ipc_socket.c 프로젝트: jnpkrn/libqb
/*
 * recv a message of unknown size.
 */
static ssize_t
qb_ipc_us_recv_at_most(struct qb_ipc_one_way *one_way,
		       void *msg, size_t len, int32_t timeout)
{
	int32_t result;
	int32_t final_rc = 0;
	int32_t to_recv = 0;
	char *data = msg;
	struct ipc_us_control *ctl = NULL;
	int32_t time_waited = 0;
	int32_t time_to_wait = timeout;

	if (timeout == -1) {
		time_to_wait = 1000;
	}

	qb_sigpipe_ctl(QB_SIGPIPE_IGNORE);

retry_peek:
	result = recv(one_way->u.us.sock, data,
		      sizeof(struct qb_ipc_request_header),
		      MSG_NOSIGNAL | MSG_PEEK);

	if (result == -1) {

		if (errno != EAGAIN) {
			final_rc = -errno;
#if !(defined(QB_LINUX) || defined(QB_CYGWIN))
			if (errno == ECONNRESET || errno == EPIPE) {
				final_rc = -ENOTCONN;
			}
#endif
			goto cleanup_sigpipe;
		}

		/* check to see if we have enough time left to try again */
		if (time_waited < timeout || timeout == -1) {
			result = qb_ipc_us_ready(one_way, NULL, time_to_wait, POLLIN);
			if (qb_ipc_us_sock_error_is_disconnected(result)) {
				final_rc = result;
				goto cleanup_sigpipe;
			}
			time_waited += time_to_wait;
			goto retry_peek;
		} else if (time_waited >= timeout) {
			final_rc = -ETIMEDOUT;
			goto cleanup_sigpipe;
		}
	}
	if (result >= sizeof(struct qb_ipc_request_header)) {
		struct qb_ipc_request_header *hdr = NULL;
		hdr = (struct qb_ipc_request_header *)msg;
		to_recv = hdr->size;
	}

	result = recv(one_way->u.us.sock, data, to_recv,
		      MSG_NOSIGNAL | MSG_WAITALL);
	if (result == -1) {
		final_rc = -errno;
		goto cleanup_sigpipe;
	} else if (result == 0) {
		qb_util_log(LOG_DEBUG, "recv == 0 -> ENOTCONN");

		final_rc = -ENOTCONN;
		goto cleanup_sigpipe;
	}

	final_rc = result;

	ctl = (struct ipc_us_control *)one_way->u.us.shared_data;
	if (ctl) {
		(void)qb_atomic_int_dec_and_test(&ctl->sent);
	}

cleanup_sigpipe:
	qb_sigpipe_ctl(QB_SIGPIPE_DEFAULT);
	return final_rc;
}