/* ==== gzip.c ============================================================
 * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *  This product includes software developed by Chris Provenzano.
 * 4. The name of Chris Provenzano may not be used to endorse or promote 
 *	  products derived from this software without specific prior written
 *	  permission.
 *
 * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE.
 *
 * Description : Push a pthread that compresses a stream but only compress 
 *				 if the I/O is too slow.
 *
 *  1.00 95/10/28 proven
 *      -Started coding this file.
 */

#define PPS_ALWAYS			0x0000
#define PPS_NEVER			0x0001		/* Kinda silly */
#define PPS_CHANGE_NEVER	0x0002
#define PPS_CHANGE_ONCE		0x0004
#define PPS_USE_FUNCTION	0x0008
/* =============================================================================
 *
 */
pthread_push_stream(int in_fd, int out_fd, int flags,
  void * (* function_name(int in, int out)))
{
	pthread_create().

}

/* =============================================================================
 *
 */
pthread_init_stream(int in_fd, int out_fd, int flags,
  void * (* function_name(int in, int out)))
{

}

stream_buf {
	ssize_t	buf_count;
	size_t	buf_size;
	void *	buf_data;
};

/* =============================================================================
 *
 */
stream_read(int in, stream_fd out  int out_fd, int flags,
  void * (* function_name(int in, int out)))
{
	stream_buf stream;

	stream.buf_size = mtu;
	if ((stream.buf_data = stream_alloc(mtu))

	while (stream.buf_count = read(in_fd, stream.buf_data, mtu)) {
		if (stream.buf_count < 0)
		
		stream_put
	}
}

pthread_stream_read


stream_buf {
	size_t	buf_count;
	size_t	buf_off;
	size_t	buf_size;
	void *	buf_data;
};

int canceled;
typedef struct stream_fd {
	pthread_mutex_t	  mutex;
	pthread_cond_t	  cond;
	stream			* empty;
	stream			* full;
} stream_fd;

stream_get(stream_fd * fd, stream_buf * buf)
{
	pthread_mutex_lock(fd->mutex);
	while (fd->full == NULL) {
		stream_wait(fd->cond, fd->mutex);
	}
	/* Do data copy here */
	pthread_mutex_unlock(fd->mutex);
}

stream_lock()

comp_thread_routine()
{
	pthread_cancel_settype(ASYNC);
	pthread_cancel_settype(DEFFERED);
	pthread_mutex_lock(comp_thread_arg.mutex);
		comp_thread_arg.finished = TRUE;
	pthread_mutex_unlock(comp_thread_arg.mutex);
}

stream_buf[4];
{
	stream_buf stream, comp_stream;

	comp_thread_arg {
		stream_buf 		* in;
		stream_buf 		* out;
		pthread_mutex_t	  mutex;
		int				  finished;
	}

	stream_alloc(&comp_stream);
	while (stream_get(&stream)) {
		stream_lock(stream_out_fd)
		if (stream_out_fd->full) {
			stream_alloc(&comp_stream); 
			comp_thread_arg.in = stream;
			comp_thread_arg.out = comp_stream;
			pthread_create(&comp_thread, comp_thread_attr, 
			  comp_thread_routine, &comp_thread_arg);
			do { /* Now just wait until the out stream is ready */
				stream_wait(stream_out_fd);
			while (stream_out_fd->full);

			pthread_mutex_lock(comp_thread_arg.mutex);
			if (comp_thread_arg.finished)
				stream_put(stream_out_fd, stream_comp);
			} else {
				stream_put(stream_out_fd, stream);
				pthread_schedparam(comp_thread, /* Raise priority to that of current thread */
				pthread_mutex_unlock(comp_thread_arg.mutex);
				pthread_cancel(comp_thread);
				pthread_join(comp_thread);
			}
		}
	}
}



		

	
	
}









