/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program 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.

**********************************************************************/



#ifndef ___QUEUE_H___
#define ___QUEUE_H___

#include	"task.h"
#include	"long_char.h"
#include	"utils.h"

#define CQ_END	0x7fffffff

typedef struct q_header {
	struct q_header *	next;
	L_CHAR *		key;
	int			pri;
	struct sys_queue *	ins;
	char *			file;
	int			line;
} Q_HEADER;

typedef struct key_list {
	struct key_list *	next;
	L_CHAR *		key;
	int			cnt;
	int			task_asign;
} KEY_LIST;

typedef struct sys_queue {
	SEM *			target_lock;

	int			flags;
#define QFM_DIRECT		0x00000003
#define QF_FIFO			0x00000000
#define QF_STACK		0x00000001
#define QF_PRI_FIFO		0x00000002
#define QF_PRI_STACK		0x00000003
#define QF_HIGH			0x00000010

	void			(*gc_func)();
	void			(*gc_get)();

	void			(*key_func)(TKEY);

	int			pri;
	int			key_limit;
	int			total_limit;

	Q_HEADER *		head;
	Q_HEADER *		tail;


	KEY_LIST *		keylist;
	int			total_cnt;

	int			cond_del_wait_cnt;

	void *			work;

	struct sys_queue *	next;
} SYS_QUEUE;

#define Q_WAIT_NOWAIT		0
#define Q_WAIT_WAIT		1
#define Q_WAIT_FORCE_INSERT	2

void setup_queue(SYS_QUEUE * q);
int xx_insert_queue(SYS_QUEUE * q,void * n,int wait_flag,char*,int);
#define insert_queue(q,n,w)	xx_insert_queue(q,n,w,__FILE__,__LINE__)
int insert_queue_offset(SYS_QUEUE * q,void * n,int offset,int wait_flag);
void *
delete_queue(SYS_QUEUE * q,int (*cond)(),void * work,int wait_flag);
L_CHAR * touch_qkey(SYS_QUEUE * q);
void release_qkey(SYS_QUEUE * q,L_CHAR * key);
int sq_key_cond(SYS_QUEUE *,void *,void *);
L_CHAR *  xx_get_server_key(URL * u,char * prefix,char *,int);
#define get_server_key(u,prefix)	xx_get_server_key((u),(prefix),__FILE__,__LINE__)
int check_queue(SYS_QUEUE * q,int (*cond)(),void * work);
void * xx_new_queue_node(int,char*,int);
#define new_queue_node(s)	xx_new_queue_node((s),__FILE__,__LINE__)
int get_active_que_thread(SYS_QUEUE*);
void gc_queue_lock();
void gc_queue_lock_high();
void gc_queue_unlock();
void gc_queue();
void init_queue();
int release_queue(SYS_QUEUE * q);
void print_key_list(SYS_QUEUE * q);
int get_key_count(SYS_QUEUE * q,L_CHAR * key);

#endif

