/**********************************************************************
 
	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.

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


#include	"task.h"
#include	"lock_level.h"
#include	"long_char.h"
#include	"memory_debug.h"
#include	"utils.h"
#include	"gbpmd.h"

typedef struct pmd_que {
	struct pmd_que *	next;
	L_CHAR *		db;
	L_CHAR *		target;
	int			interval;
} PMD_QUE;

SEM pmd_que_lock;
PMD_QUE * pmd_que_head;
PMD_QUE * pmd_que_tail;
int pmd_que_status;

void
init_pmd_queue()
{
	pmd_que_lock = new_lock(LL_PMD);
	pmd_que_status = 1;
}

void
insert_pmd_que(L_CHAR * db,L_CHAR * target,int interval)
{
PMD_QUE * p;
	p = d_alloc(sizeof(*p));
	p->db = ll_copy_str(db);
	p->target = ll_copy_str(target);
	p->interval = interval;
	p->next = 0;
	lock_task(pmd_que_lock);
	if ( pmd_que_head ) {
		pmd_que_tail->next = p;
		pmd_que_tail = p;
	}
	else 	pmd_que_head = pmd_que_tail = p;
	wakeup_task((int)&pmd_que_head);
	unlock_task(pmd_que_lock,"insert_pmd_que");
}

void
delete_pmd_que(L_CHAR ** db,L_CHAR ** target,int * interval)
{
PMD_QUE * p;
	lock_task(pmd_que_lock);
	for ( ; pmd_que_head == 0 ; ) {
		switch ( pmd_que_status ) {
		case 0:
		case 1:
			pmd_que_status = 0;
			break;
		case 2:
		case 4:
			pmd_que_status = 1;
			break;
		case 3:
			pmd_que_status = 0;
			break;
		}
		sleep_task((int)&pmd_que_head,pmd_que_lock);
		lock_task(pmd_que_lock);
	}
	p = pmd_que_head;
	pmd_que_head = p->next;
	if ( pmd_que_head == 0 )
		pmd_que_tail = 0;
	*db = p->db;
	*target = p->target;
	*interval = p->interval;
	if ( l_strcmp(p->target,l_string(std_cm,"target")) )
		pmd_que_status = 2;
	else if ( pmd_que_status )
		pmd_que_status = 4;
	else	pmd_que_status = 3;
	d_f_ree(p);
	unlock_task(pmd_que_lock,"delete_pmd_que");
}

int
check_pmd_que()
{
int ret;
	lock_task(pmd_que_lock);
	if ( pmd_que_status )
		ret = 1;
	else	ret = 0;
	if ( pmd_que_status == 1 )
		pmd_que_status = 0;
	unlock_task(pmd_que_lock,"check_pmd_que");
	return ret;
}
