Some kind of general purpose C library. This is discontinued and only kept as a reference just in case I need something from it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

245 lines
6.5 KiB

#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <scot/stream_pool.h>
#include <scot/stream_pool_fraction.h>
#include <scot/event_listener.h>
#include <scot/exception.h>
#include <scot/stream.h>
#include <scot/memory.h>
#include <scot/thread.h>
#define GEN_LOCAL
# include <scot/list.h>
#undef GEN_LOCAL
GEN_LIST_FUNC_PROTO (scot_sp_fraction);
GEN_LIST_IMPL (scot_sp_fraction);
/*
* static functions for this file
* ----------------------------------------------------------------------
*/
static
int
scot_get_free_spf_by_type (const struct scot_sp_fraction * a,
const struct scot_sp_fraction * b)
{
if (a->stream_type != b->stream_type ||
b->s_count >= SCOT_MAX_FRACTION) /* b ist der node bei find. */
return -1;
return 0;
}
static
int
scot_get_spf_by_stream_handle (const struct scot_sp_fraction * a,
const struct scot_sp_fraction * b)
{
int i;
for (i = 0; i < SCOT_MAX_FRACTION && b->s_list [i] != a->s_list [0]; i++);
if (i >= SCOT_MAX_FRACTION)
return -1;
return 0;
}
/* ---------------------------------------------------------------------- */
/*
* Es wäre sicher auch schön eine Funktion zu haben, die einen Stream
* nach dem anderen (die in dem Stream Pool registriert sind)....oder aber
* eine komplette Liste aller in einem Pool registrierten Streams zurückgibt.
* So kann man bevor man einen StreamPool freigibt erstmal alle Streams
* rausholen (und evtl. auch freigeben.)
*/
struct scot_stream *
scot_sp_get_all_streams (struct scot_stream_pool * sp)
{
}
/*
* adds the given stream s->handle to the fd_set specified via
* rwe_mask. If the stream is not already under control of this
* stream pool it is added to s_list. Else only the flags within
* rfds, wfds and efds are updated. This function will never clean
* a flag, but only set them.
*/
void
scot_stream_pool_add (
struct scot_stream_pool * sp,
struct scot_stream * s,
int rwe_mask)
{
struct scot_event_listener * l = (struct scot_event_listener *) sp;
struct scot_sp_fraction * f_search;
list_scot_sp_fraction_node_t * f_node;
struct scot_sp_fraction * f;
/*
* soweit ich das in erinnerung habe sind meine listen nicht per se
* thread save. Daher sollte hier unbedingt noch ein mutex her,
* damit nicht gleichzeitig in die liste geschrieben (hier)
* und gelöscht wird (in remove)
*/
LOCK_THREAD_MUTEX (&sp->mutex);
/*
* it would be nice to check if the stream is already in the pool before
* doing anything else
*/
/*
* first seek a not full fraction for s->stream_type
*/
f_search = scot_spf_new (f_search, l, s->s_type);
scot_spf_add (f_search, s, rwe_mask);
list_scot_sp_fraction_set_cmp (scot_get_free_spf_by_type);
f_node = list_scot_sp_fraction_find (sp->pool, f_search);
list_scot_sp_fraction_set_cmp (list_scot_sp_fraction_default_cmp);
if (f_node == NULL)
{
f = f_search;
list_scot_sp_fraction_insert (sp->pool, f);
}
else
{
scot_spf_free_s (f_search, SCOT_STREAM_POOL_KEEP_STREAMS);
scot_spf_free (f_search);
f = list_scot_sp_fraction_retrive (f_node);
scot_spf_add (f, s, rwe_mask);
}
scot_stream_pool_cmd (sp, SCOT_STREAM_POOL_RESTART_FRACTION, f);
UNLOCK_THREAD_MUTEX (&sp->mutex);
}
/*
* removes the given stream s->handle from the fd_set specified via
* rwe_mask. If the stream isn't left in at least one of the sets, either
* rfds, wfds or efds it is removed from s_list. This function will never
* set a flag, but the mask is used to determine where to remove fd.
*
* Diese Funktion und scot_stream_pool_add sollten sich gegenseitig
* ausschließen, um die liste immer in einem konsistenten zustand zu halten.
* Relevant sind da wohl nur threads, also sollte es ein thread_mutex tun.
*/
void
scot_stream_pool_remove (
struct scot_stream_pool * sp,
struct scot_stream * s,
int rwe_mask)
{
struct scot_event_listener * l = (struct scot_event_listener *) sp;
struct scot_sp_fraction * f_search;
list_scot_sp_fraction_node_t * f_node;
excenv_t * ee;
TRY
{
LOCK_THREAD_MUTEX (&sp->mutex);
/*
* first seek a not full fraction for s->stream_type
*/
f_search = scot_spf_new (f_search, l, s->s_type);
scot_spf_add (f_search, s, rwe_mask);
list_scot_sp_fraction_set_cmp (scot_get_spf_by_stream_handle);
f_node = list_scot_sp_fraction_find (sp->pool, f_search);
list_scot_sp_fraction_set_cmp (list_scot_sp_fraction_default_cmp);
scot_spf_free (f_search);
if (f_node == NULL)
THROW (EXC (EXC_ERROR, 345, "Can't find stream in any fraction."));
else
{
struct scot_sp_fraction * f;
scot_stream_pool_cmd (sp, SCOT_STREAM_POOL_STOP_FRACTION, f);
f = list_scot_sp_fraction_retrive (f_node);
scot_spf_remove (f, s, rwe_mask);
scot_stream_pool_cmd (sp, SCOT_STREAM_POOL_START_FRACTION, f);
}
UNLOCK_THREAD_MUTEX (&sp->mutex);
}
CATCH (ee)
{
printf ("Exception in %s (%s, %d)\n", __FUNCTION__, __FILE__, __LINE__);
forward_all_exceptions (ee);
}
}
int /* rwe_mask */
scot_stream_pool_get_rwe (
struct scot_stream_pool * sp,
struct scot_stream * s)
{
struct scot_event_listener * l = (struct scot_event_listener *) sp;
struct scot_sp_fraction * f_search;
list_scot_sp_fraction_node_t * f_node;
struct scot_sp_fraction * f;
int ret = 0;
excenv_t * ee;
TRY
{
f_search = scot_spf_new (f_search, l, s->s_type);
scot_spf_add (f_search, s, 0);
list_scot_sp_fraction_set_cmp (scot_get_spf_by_stream_handle);
f_node = list_scot_sp_fraction_find (sp->pool, f_search);
list_scot_sp_fraction_set_cmp (list_scot_sp_fraction_default_cmp);
scot_spf_free (f_search);
if (f_node == NULL)
THROW (EXC (EXC_ERROR, 987, "could not find stream in stream pool"));
else
f = list_scot_sp_fraction_retrive (f_node);
/*
* !!!FIXME!!! I will only work with sockets right now..... :-(
* Much more abstraction is in the stream code.
*/
if (FD_ISSET (s->handle.sock, &f->rfds))
ret = ret | SCOT_STREAM_POOL_FD_ADD_RMASK;
if (FD_ISSET (s->handle.sock, &f->wfds))
ret = ret | SCOT_STREAM_POOL_FD_ADD_WMASK;
if (FD_ISSET (s->handle.sock, &f->efds))
ret = ret | SCOT_STREAM_POOL_FD_ADD_EMASK;
}
CATCH (ee);
{
printf ("Exception in %s (%s, %d)\n", __FUNCTION__, __FILE__, __LINE__);
forward_all_exceptions (ee);
}
return ret;
}
void
scot_stream_pool_cmd (struct scot_stream_pool * sp, uint16_t cmd, void * arg)
{
THREAD_COND_ENTER_CS (&sp->cmd_cs);
sp->cmd = cmd;
sp->cmd_arg = arg;
SIGNAL_THREAD_COND (&sp->cmd_cond);
THREAD_COND_LEAVE_CS (&sp->cmd_cs);
}