static ret_t
poll_release (cherokee_handler_proxy_poll_t *poll,
	      cherokee_handler_proxy_conn_t *pconn)
{
	/* Not longer an active connection */
	cherokee_list_del (&pconn->listed);

	/* Don't reuse connection w/o keep-alive
	 */
	if (! pconn->keepalive_in) {
		cherokee_handler_proxy_conn_free (pconn);
		return ret_ok;
	}

	/* If the reuse-list is full, dispose the oldest obj
	 */
	if (poll->reuse_len > poll->reuse_max) {
		cherokee_handler_proxy_conn_t *oldest;

		oldest = PROXY_CONN(poll->reuse.prev);
		cherokee_list_del (&oldest->listed);
		poll->reuse_len -= 1;

		cherokee_handler_proxy_conn_free (oldest);
	}

	/* Clean up
	 */
	pconn->keepalive_in = false;
	pconn->size_in      = 0;
	pconn->sent_out     = 0;
	pconn->enc          = pconn_enc_none;

	pconn->post.do_buf_sent = true;
	pconn->post.sent        = 0;

	cherokee_buffer_clean (&pconn->post.buf_temp);
	cherokee_buffer_clean (&pconn->header_in_raw);

	/* Store it to be reused
	 */
	poll->reuse_len += 1;
	cherokee_list_add (&pconn->listed, &poll->reuse);

	return ret_ok;
}
ret_t
cherokee_handler_proxy_poll_get (cherokee_handler_proxy_poll_t  *poll,
				 cherokee_handler_proxy_conn_t **pconn,
				 cherokee_source_t              *src)
{
	ret_t            ret;
	cherokee_list_t *i;

	CHEROKEE_MUTEX_LOCK (&poll->mutex);

	if (poll->reuse_len > 0) {
		/* Reuse a prev connection */
		poll->reuse_len -= 1;

		i = poll->reuse.prev;
		cherokee_list_del (i);
		cherokee_list_add (i, &poll->active);

		*pconn = PROXY_CONN(i);
	} else {
		cherokee_handler_proxy_conn_t *n;

		/* Create a new connection */
		ret = cherokee_handler_proxy_conn_new (&n);
		if (ret != ret_ok)
			goto error;

		ret = cherokee_proxy_util_init_socket (&n->socket, src);
		if (ret != ret_ok) {
			cherokee_handler_proxy_conn_free (n);
			goto error;
		}

		cherokee_list_add (&n->listed, &poll->active);
		n->poll_ref = poll;
		*pconn = n;
	}

	CHEROKEE_MUTEX_UNLOCK (&poll->mutex);
	return ret_ok;
error:
	CHEROKEE_MUTEX_UNLOCK (&poll->mutex);
	return ret_error;
}
Ejemplo n.º 3
0
void
cherokee_list_sort (cherokee_list_t *head, int (*cmp)(cherokee_list_t *a, cherokee_list_t *b))
{
	cherokee_list_t *p, *q, *e, *list, *tail, *oldhead;
	int insize, nmerges, psize, qsize, i;

	list = head->next;
	cherokee_list_del(head);
	insize = 1;
	for (;;) {
		p = oldhead = list;
		list = tail = NULL;
		nmerges = 0;

		while (p) {
			nmerges++;
			q = p;
			psize = 0;
			for (i = 0; i < insize; i++) {
				psize++;
				q = q->next == oldhead ? NULL : q->next;
				if (!q)
					break;
			}

			qsize = insize;
			while (psize > 0 || (qsize > 0 && q)) {
				if (!psize) {
					e = q;
					q = q->next;
					qsize--;
					if (q == oldhead)
						q = NULL;
				} else if (!qsize || !q) {
					e = p;
					p = p->next;
					psize--;
					if (p == oldhead)
						p = NULL;
				} else if (cmp(p, q) <= 0) {
					e = p;
					p = p->next;
					psize--;
					if (p == oldhead)
						p = NULL;
				} else {
					e = q;
					q = q->next;
					qsize--;
					if (q == oldhead)
						q = NULL;
				}
				if (tail)
					tail->next = e;
				else
					list = e;
				e->prev = tail;
				tail = e;
			}
			p = q;
		}

		tail->next = list;
		list->prev = tail;

		if (nmerges <= 1)
			break;

		insize *= 2;
	}

	head->next = list;
	head->prev = list->prev;
	list->prev->next = head;
	list->prev = head;
}