/*
 * Functions managing applets
 *
 * Copyright 2000-2015 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 <stdio.h>
#include <stdlib.h>

#include <common/config.h>
#include <common/mini-clist.h>
#include <proto/applet.h>
#include <proto/channel.h>
#include <proto/stream.h>
#include <proto/stream_interface.h>

unsigned int nb_applets = 0;
unsigned int applets_active_queue = 0;

#ifdef USE_THREAD
HA_SPINLOCK_T applet_active_lock;        /* spin lock related to applet active queue */
#endif

struct list applet_active_queue = LIST_HEAD_INIT(applet_active_queue);

void applet_run_active()
{
	struct appctx *curr, *next;
	struct stream_interface *si;
	struct list applet_cur_queue = LIST_HEAD_INIT(applet_cur_queue);

	if (!applets_active_queue)
		return;

	SPIN_LOCK(APPLETS_LOCK, &applet_active_lock);

	curr = LIST_NEXT(&applet_active_queue, typeof(curr), runq);
	while (&curr->runq != &applet_active_queue) {
		next = LIST_NEXT(&curr->runq, typeof(next), runq);
		if (curr->thread_mask & tid_bit) {
			LIST_DEL(&curr->runq);
			curr->state = APPLET_RUNNING;
			LIST_ADDQ(&applet_cur_queue, &curr->runq);
			applets_active_queue--;
		}
		curr = next;
	}

	SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);

	/* The list is only scanned from the head. This guarantees that if any
	 * applet removes another one, there is no side effect while walking
	 * through the list.
	 */
	while (!LIST_ISEMPTY(&applet_cur_queue)) {
		curr = LIST_ELEM(applet_cur_queue.n, typeof(curr), runq);
		si = curr->owner;

		/* Now we'll try to allocate the input buffer. We wake up the
		 * applet in all cases. So this is the applet responsibility to
		 * check if this buffer was allocated or not. This let a chance
		 * for applets to do some other processing if needed. */
		if (!channel_alloc_buffer(si_ic(si), &curr->buffer_wait))
			si_applet_cant_put(si);

		/* We always pretend the applet can't get and doesn't want to
		 * put, it's up to it to change this if needed. This ensures
		 * that one applet which ignores any event will not spin.
		 */
		si_applet_cant_get(si);
		si_applet_stop_put(si);

		curr->applet->fct(curr);
		si_applet_wake_cb(si);
		channel_release_buffer(si_ic(si), &curr->buffer_wait);

		if (applet_cur_queue.n == &curr->runq) {
			/* curr was left in the list, move it back to the active list */
			LIST_DEL(&curr->runq);
			LIST_INIT(&curr->runq);
			SPIN_LOCK(APPLETS_LOCK, &applet_active_lock);
			if (curr->state & APPLET_WANT_DIE) {
				curr->state = APPLET_SLEEPING;
				__appctx_free(curr);
			}
			else {
				if (curr->state & APPLET_WOKEN_UP) {
					curr->state = APPLET_SLEEPING;
					__appctx_wakeup(curr);
				}
				else {
					curr->state = APPLET_SLEEPING;
				}
			}
			SPIN_UNLOCK(APPLETS_LOCK, &applet_active_lock);
		}
	}
}

__attribute__((constructor))
static void __applet_init(void)
{
	SPIN_INIT(&applet_active_lock);
}
