/*
 * Queue management functions.
 *
 * Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <common/config.h>
#include <common/time.h>

#include <types/proxy.h>
#include <types/session.h>

#include <proto/queue.h>
#include <proto/server.h>
#include <proto/task.h>


void **pool_pendconn = NULL;

/* returns the effective dynamic maxconn for a server, considering the minconn
 * and the proxy's usage relative to its dynamic connections limit. It is
 * expected that 0 < s->minconn <= s->maxconn when this is called.
 */
unsigned int srv_dynamic_maxconn(const struct server *s)
{
	if (s->proxy->beconn >= s->proxy->fullconn)
		/* no fullconn or proxy is full */
		return s->maxconn;

	if (s->minconn == s->maxconn)
		/* static limit */
		return s->maxconn;

	return MAX(s->minconn,
		   s->proxy->beconn * s->maxconn / s->proxy->fullconn);
}


/*
 * Manages a server's connection queue. If woken up, will try to dequeue as
 * many pending sessions as possible, and wake them up. The task has nothing
 * else to do, so it always returns TIME_ETERNITY.
 */
int process_srv_queue(struct task *t)
{
	struct server *s = (struct server*)t->context;
	struct proxy  *p = s->proxy;
	int xferred;

	/* First, check if we can handle some connections queued at the proxy. We
	 * will take as many as we can handle.
	 */
	for (xferred = 0; s->cur_sess + xferred < srv_dynamic_maxconn(s); xferred++) {
		struct session *sess;

		sess = pendconn_get_next_sess(s, p);
		if (sess == NULL)
			break;
		task_wakeup(sess->task);
	}

	return TIME_ETERNITY;
}

/* Detaches the next pending connection from either a server or a proxy, and
 * returns its associated session. If no pending connection is found, NULL is
 * returned. Note that neither <srv> nor <px> can be NULL.
 */
struct session *pendconn_get_next_sess(struct server *srv, struct proxy *px)
{
	struct pendconn *p;
	struct session *sess;

	p = pendconn_from_srv(srv);
	if (!p) {
		p = pendconn_from_px(px);
		if (!p)
			return NULL;
		p->sess->srv = srv;
	}
	sess = p->sess;
	pendconn_free(p);
	return sess;
}

/* Adds the session <sess> to the pending connection list of server <sess>->srv
 * or to the one of <sess>->proxy if srv is NULL. All counters and back pointers
 * are updated accordingly. Returns NULL if no memory is available, otherwise the
 * pendconn itself.
 */
struct pendconn *pendconn_add(struct session *sess)
{
	struct pendconn *p;

	p = pool_alloc(pendconn);
	if (!p)
		return NULL;

	sess->pend_pos = p;
	p->sess = sess;
	p->srv  = sess->srv;
	if (sess->srv) {
		LIST_ADDQ(&sess->srv->pendconns, &p->list);
		sess->logs.srv_queue_size += sess->srv->nbpend;
		sess->srv->nbpend++;
		if (sess->srv->nbpend > sess->srv->nbpend_max)
			sess->srv->nbpend_max = sess->srv->nbpend;
	} else {
		LIST_ADDQ(&sess->be->pendconns, &p->list);
		sess->logs.prx_queue_size += sess->be->nbpend;
		sess->be->nbpend++;
		if (sess->be->nbpend > sess->be->nbpend_max)
			sess->be->nbpend_max = sess->be->nbpend;
	}
	sess->be->totpend++;
	return p;
}

/*
 * Detaches pending connection <p>, decreases the pending count, and frees
 * the pending connection. The connection might have been queued to a specific
 * server as well as to the proxy. The session also gets marked unqueued.
 */
void pendconn_free(struct pendconn *p)
{
	LIST_DEL(&p->list);
	p->sess->pend_pos = NULL;
	if (p->srv)
		p->srv->nbpend--;
	else
		p->sess->be->nbpend--;
	p->sess->be->totpend--;
	pool_free(pendconn, p);
}


/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
