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

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


#define STREAM_LIB

#include	"stream.h"
#include	"task.h"

extern SEM stream_lock;

void (*stream_gc)();

STREAM * stream_list;

void
_s_open(STREAM * s,int mode)
{
	s->h.mode = mode&0xf;
	s->h.cm = std_cm;
	s->h.cm_work = (*s->h.cm->open)();
	s->h.cr_cnt = 0;
	s->h.cr_mode = 0;
	s->h.wb_flags = 0;
	init_sbuf(&s->h.write_buf,0);
	s->h.next = stream_list;
	s->h.interval = INITIAL_INTERVAL;
	s->h.bytes_per_interval = 0;
	s->h.last_time = get_xltime();
	s->h.avg_thput = -1;
	s->h.usec_per_byte = -1;
	s->h.pushed = 0;
	s->h.pushed_flag = 0;
	s->h.thread = 0;
	stream_list = s;
}


int
s_stream_nos()
{
int ret;
STREAM * s;
	ret = 0;
	lock_task(stream_lock);
	for ( s = stream_list ; s ; s = s->h.next , ret ++ );
	unlock_task(stream_lock,"s_stream_nos");
	return ret;
}



void
_s_insert_thread(STREAM * s,S_FILE_THREAD * t)
{
	t->tid = get_tid();
	t->next = s->h.thread;
	s->h.thread = t;
}

void
_s_delete_thread(STREAM * s,S_FILE_THREAD * t)
{
S_FILE_THREAD ** tp;

	for ( tp = &s->h.thread ; *tp ; tp = &(*tp)->next )
		if ( *tp == t ) {
			*tp = t->next;
			break;
		}
	if ( s->h.tbl == 0 )
		wakeup_task((int)&s->h.thread);
}

void
s_delete_thread(STREAM * s,S_FILE_THREAD * t)
{
	lock_task(stream_lock);
	_s_delete_thread(s,t);
	unlock_task(stream_lock,"s_delete_thread");
}