/*
 * include/proto/applet.h
 * This file contains applet function prototypes
 *
 * Copyright (C) 2000-2015 Willy Tarreau - w@1wt.eu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _PROTO_APPLET_H
#define _PROTO_APPLET_H

#include <stdlib.h>

#include <common/config.h>
#include <common/mini-clist.h>
#include <types/applet.h>
#include <proto/connection.h>

extern unsigned int nb_applets;
extern unsigned int applets_active_queue;
__decl_hathreads(extern HA_SPINLOCK_T applet_active_lock);
extern struct list applet_active_queue;

void applet_run_active();


static int inline appctx_res_wakeup(struct appctx *appctx);


/* Initializes all required fields for a new appctx. Note that it does the
 * minimum acceptable initialization for an appctx. This means only the
 * 3 integer states st0, st1, st2 are zeroed.
 */
static inline void appctx_init(struct appctx *appctx, unsigned long thread_mask)
{
	appctx->st0 = appctx->st1 = appctx->st2 = 0;
	appctx->io_release = NULL;
	appctx->thread_mask = thread_mask;
	appctx->state = APPLET_SLEEPING;
}

/* Tries to allocate a new appctx and initialize its main fields. The appctx
 * is returned on success, NULL on failure. The appctx must be released using
 * pool_free2(connection) or appctx_free(), since it's allocated from the
 * connection pool. <applet> is assigned as the applet, but it can be NULL.
 */
static inline struct appctx *appctx_new(struct applet *applet, unsigned long thread_mask)
{
	struct appctx *appctx;

	appctx = pool_alloc2(pool2_connection);
	if (likely(appctx != NULL)) {
		appctx->obj_type = OBJ_TYPE_APPCTX;
		appctx->applet = applet;
		appctx_init(appctx, thread_mask);
		LIST_INIT(&appctx->runq);
		LIST_INIT(&appctx->buffer_wait.list);
		appctx->buffer_wait.target = appctx;
		appctx->buffer_wait.wakeup_cb = (int (*)(void *))appctx_res_wakeup;
		HA_ATOMIC_ADD(&nb_applets, 1);
	}
	return appctx;
}

/* Releases an appctx previously allocated by appctx_new(). Note that
 * we share the connection pool.
 */
static inline void __appctx_free(struct appctx *appctx)
{
	if (!LIST_ISEMPTY(&appctx->runq)) {
		LIST_DEL(&appctx->runq);
		applets_active_queue--;
	}

	if (!LIST_ISEMPTY(&appctx->buffer_wait.list)) {
		HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
		LIST_DEL(&appctx->buffer_wait.list);
		LIST_INIT(&appctx->buffer_wait.list);
		HA_SPIN_UNLOCK(BUF_WQ_LOCK, &buffer_wq_lock);
	}

	pool_free2(pool2_connection, appctx);
	HA_ATOMIC_SUB(&nb_applets, 1);
}
static inline void appctx_free(struct appctx *appctx)
{
	HA_SPIN_LOCK(APPLETS_LOCK, &applet_active_lock);
	if (appctx->state & APPLET_RUNNING) {
		appctx->state |= APPLET_WANT_DIE;
		HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
		return;
	}
	__appctx_free(appctx);
	HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
}

/* wakes up an applet when conditions have changed */
static inline void __appctx_wakeup(struct appctx *appctx)
{
	if (LIST_ISEMPTY(&appctx->runq)) {
		LIST_ADDQ(&applet_active_queue, &appctx->runq);
		applets_active_queue++;
	}
}

static inline void appctx_wakeup(struct appctx *appctx)
{
	HA_SPIN_LOCK(APPLETS_LOCK, &applet_active_lock);
	if (appctx->state & APPLET_RUNNING) {
		appctx->state |= APPLET_WOKEN_UP;
		HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
		return;
	}
	__appctx_wakeup(appctx);
	HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
}

/* Callback used to wake up an applet when a buffer is available. The applet
 * <appctx> is woken up is if it is not already in the list of "active"
 * applets. This functions returns 1 is the stream is woken up, otherwise it
 * returns 0. If task is running we request we check if woken was already
 * requested */
static inline int appctx_res_wakeup(struct appctx *appctx)
{
	HA_SPIN_LOCK(APPLETS_LOCK, &applet_active_lock);
	if (appctx->state & APPLET_RUNNING) {
		if (appctx->state & APPLET_WOKEN_UP) {
			HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
			return 0;
		}
		appctx->state |= APPLET_WOKEN_UP;
		HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
		return 1;
	}
	__appctx_wakeup(appctx);
	HA_SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
	return 1;
}


#endif /* _PROTO_APPLET_H */

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