stream_pool_fraction.c 3.34 KB
#ifndef WIN32
# include <sys/select.h>
# include <sys/types.h>
# include <unistd.h>
# include <errno.h>
#else
# include <Windows.h>
# include <Winsock2.h>
#endif

#include <scot/stream_pool.h>
#include <scot/stream_pool_fraction.h>

#include <scot/event_listener.h>
#include <scot/exception.h>
#include <scot/event.h>
#include <scot/stream.h>
#include <scot/memory.h>
#include <scot/thread.h>


/*
 * static functions for this file
 * ----------------------------------------------------------------------
 */
/* ---------------------------------------------------------------------- */

struct scot_sp_fraction * 
scot_spf_new (struct scot_sp_fraction * f,
              struct scot_event_listener * e,
				  int s_type)
{
	f = SCOT_MEM_GET (sizeof (struct scot_sp_fraction));
	SCOT_MEM_ZERO (f, sizeof (struct scot_sp_fraction));

#ifdef WIN32
	f->Event = WSACreateEvent();
#endif

	f->el             = e;
	f->stream_type    = s_type;
	f->spf_entry_func = scot_spf_thread_func[s_type];

	return f;
}

void
scot_spf_set_free_streams (struct scot_sp_fraction * f, int free_s)
{
	f->free_s = free_s;
}

void
scot_spf_free (struct scot_sp_fraction * f)
{
	int i;

	if (f->s_count != 0 && f->free_s != 0)
	{
		for (i=0; i<SCOT_MAX_FRACTION; i++)
		{
			if (f->s_list[i] != NULL)
				SCOT_STREAM_FREE (f->s_list[i]);
		}
	}

#ifdef WIN32
	WSACloseEvent(f->Event);
#endif

	SCOT_MEM_FREE (f);
}

void
scot_spf_free_s (struct scot_sp_fraction * f, int free_s)
{
	f->free_s = free_s;
}

void 
scot_spf_add (struct scot_sp_fraction * spf, 
              struct scot_stream *      s,
				  int                       rwe_mask)
{
	int i;
	excenv_t * ee;

	TRY
	{
		for (i = 0; spf->s_list [i] != NULL && i < SCOT_MAX_FRACTION; i++);

		if (i >= SCOT_MAX_FRACTION)
			THROW (EXC (EXC_ERROR, 123, "fraction count < SCOT_MAX_FRACTION"
						" but no element != NULL found"));

		spf->s_count ++;
		spf->s_list [i] = s;

		scot_stream_set_nonblock (s);

		/* for select */
		if (s->handle.sock > spf->max_fd)
			spf->max_fd = s->handle.sock;
		if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_RMASK)
			FD_SET (s->handle.sock, &spf->rfds);
		if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_WMASK)
			FD_SET (s->handle.sock, &spf->wfds);
		if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_EMASK)
			FD_SET (s->handle.sock, &spf->efds);
	}
	CATCH (ee)
	{
		printf ("Exception in %s (%s, %d)\n", __FUNCTION__, __FILE__, __LINE__);
		forward_all_exceptions (ee);
	}
}

void 
scot_spf_remove (struct scot_sp_fraction * spf, 
                 struct scot_stream *      s,
					  int                       rwe_mask)
{
	int i;

	if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_RMASK)
		FD_CLR (s->handle.sock, &spf->rfds);
	if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_WMASK)
		FD_CLR (s->handle.sock, &spf->wfds);
	if (rwe_mask & SCOT_STREAM_POOL_FD_ADD_EMASK)
		FD_CLR (s->handle.sock, &spf->efds);

	if (! FD_ISSET (s->handle.sock, &spf->rfds) &&
	    ! FD_ISSET (s->handle.sock, &spf->wfds) &&
	    ! FD_ISSET (s->handle.sock, &spf->efds))
	{
		spf->max_fd = 0;

		for (i=0; i<SCOT_MAX_FRACTION; i++)
		{
			if (spf->s_list [i] == s)
			{
				SCOT_MEM_MOVE (
						&(spf->s_list [i]), &(spf->s_list [i+1]), 
						(SCOT_MAX_FRACTION-i) * sizeof (struct scot_stream *));
				spf->s_list [SCOT_MAX_FRACTION-1-i] = NULL;
				spf->s_count --;
			}

			if (spf->s_list [i] != NULL && 
			    spf->s_list [i]->handle.sock > spf->max_fd)
				spf->max_fd = spf->s_list[i]->handle.sock;
		}
	}
}