/**********************************************************************
 
	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	<signal.h>
#include	<errno.h>
#include	"machine/include.h"
#include	"task.h"
#include	"pri_level.h"
#include	"stream.h"
#include	"lock_level.h"

extern SEM stream_lock;

void sigusr1_handler();

STREAM * close_stream;

void
close_sync_task();

void
init_machine_stream()
{
struct sigaction sa;

	create_task(close_sync_task,0,PRI_TICK_CLOSE);

	sa.sa_handler = sigusr1_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_INTERRUPT;
	sigaction(SIGUSR1,&sa,0);

	init_file_stream();
	init_terminal_stream();
	init_flush_pipe_stream();
}

void sigusr1_handler()
{
/*
	if ( signal(SIGUSR1,sigusr1_handler) < 0 )
		printf("USR %i %i error %i\n",get_tid(),getpid(),errno);
*/
}


void
close_sync_task()
{
	for ( ; ; ) {
		sleep_sec(2);
		lock_task(stream_lock);
		if ( close_stream )
			wakeup_task((int)&close_stream->h.thread);
		unlock_task(stream_lock,"close_sync_func");
	}
}


void
_s_close_sync(STREAM * s)
{
int mode;
int tid;

	for ( ; close_stream ; ) {
		sleep_task((int)&close_stream,stream_lock);
		lock_task(stream_lock);
	}
	close_stream = s;

	for ( ; ; ) {
		if ( s->h.thread == 0 )
			break;
		wakeup_task((int)s);
		pthread_kill(get_hard_tid(s->h.thread->tid),
				SIGUSR1);
		sleep_task((int)&s->h.thread,stream_lock);
		lock_task(stream_lock);
	}
	close_stream = 0;
	wakeup_task((int)&close_stream);
}
