enhanced zombie device handling and improved the process pipe device

This commit is contained in:
hyung-hwan 2016-04-17 17:00:58 +00:00
parent 8b5a5bbc4f
commit 3ca7bcd549
10 changed files with 266 additions and 101 deletions

View File

@ -36,7 +36,7 @@ libstio_la_SOURCES = \
stio-tmr.c stio-tmr.c
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libstio_la_LIBADD = $(LIBADD_LIB_COMMON) libstio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
bin_PROGRAMS = stio bin_PROGRAMS = stio
stio_SOURCES = main.c stio_SOURCES = main.c

View File

@ -102,7 +102,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
LTLIBRARIES = $(lib_LTLIBRARIES) LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 = am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \ am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
libstio_la-stio-sck.lo libstio_la-stio-tim.lo \ libstio_la-stio-sck.lo libstio_la-stio-tim.lo \
libstio_la-stio-tmr.lo libstio_la-stio-tmr.lo
@ -342,7 +342,7 @@ libstio_la_SOURCES = \
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libstio_la_LIBADD = $(LIBADD_LIB_COMMON) libstio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
stio_SOURCES = main.c stio_SOURCES = main.c
stio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) stio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
stio_LDFLAGS = $(LDFLAGS_LIB_COMMON) stio_LDFLAGS = $(LDFLAGS_LIB_COMMON)

View File

@ -40,6 +40,17 @@
#include <netpacket/packet.h> #include <netpacket/packet.h>
#include <net/if.h> #include <net/if.h>
#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
# include <openssl/ssl.h>
# if defined(HAVE_OPENSSL_ERR_H)
# include <openssl/err.h>
# endif
# if defined(HAVE_OPENSSL_ENGINE_H)
# include <openssl/engine.h>
# endif
# define USE_SSL
#endif
/* ========================================================================= */ /* ========================================================================= */
struct mmgr_stat_t struct mmgr_stat_t
@ -86,6 +97,22 @@ static stio_mmgr_t mmgr =
/* ========================================================================= */ /* ========================================================================= */
#if defined(USE_SSL)
static void cleanup_openssl ()
{
/* ERR_remove_state() should be called for each thread if the application is thread */
ERR_remove_state (0);
#if defined(HAVE_ENGINE_CLEANUP)
ENGINE_cleanup ();
#endif
ERR_free_strings ();
EVP_cleanup ();
#if defined(HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
CRYPTO_cleanup_all_ex_data ();
#endif
}
#endif
struct tcp_server_t struct tcp_server_t
{ {
int tally; int tally;
@ -243,10 +270,11 @@ static void handle_signal (int sig)
int main () int main ()
{ {
int i;
stio_t* stio; stio_t* stio;
stio_dev_sck_t* sck; stio_dev_sck_t* sck;
stio_dev_sck_t* tcp[2]; stio_dev_sck_t* tcp[3];
struct sigaction sigact; struct sigaction sigact;
stio_dev_sck_connect_t tcp_conn; stio_dev_sck_connect_t tcp_conn;
@ -257,6 +285,11 @@ int main ()
stio_dev_sck_make_t sck_make; stio_dev_sck_make_t sck_make;
tcp_server_t* ts; tcp_server_t* ts;
#if defined(USE_SSL)
SSL_load_error_strings ();
SSL_library_init ();
#endif
stio = stio_open (&mmgr, 0, 512, STIO_NULL); stio = stio_open (&mmgr, 0, 512, STIO_NULL);
if (!stio) if (!stio)
{ {
@ -322,10 +355,13 @@ int main ()
goto oops; goto oops;
} }
/* -------------------------------------------------------------- */
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_sck_on_write; tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read; tcp_make.on_read = tcp_sck_on_read;
tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make); tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[1]) if (!tcp[1])
{ {
@ -337,6 +373,45 @@ int main ()
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind)); memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL); stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL);
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR;
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
{
printf ("stio_dev_sck_bind() failed....\n");
goto oops;
}
tcp_lstn.backlogs = 100;
tcp_lstn.on_connect = tcp_sck_on_connect;
tcp_lstn.on_disconnect = tcp_sck_on_disconnect;
if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
{
printf ("stio_dev_sck_listen() failed....\n");
goto oops;
}
/* -------------------------------------------------------------- */
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp[2] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[2])
{
printf ("Cannot make tcp\n");
goto oops;
}
ts = (tcp_server_t*)(tcp[2] + 1);
ts->tally = 0;
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
stio_sckadr_initforip4 (&tcp_bind.addr, 1235, STIO_NULL);
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR | STIO_DEV_SCK_BIND_SECURE;
tcp_bind.certfile = STIO_MT("stio.certfile");
tcp_bind.keyfile = STIO_MT("stio.keyfile");
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1) if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
{ {
@ -400,6 +475,7 @@ int main ()
#endif #endif
for (i = 0; i < 5; i++)
{ {
stio_dev_pro_t* pro; stio_dev_pro_t* pro;
stio_dev_pro_make_t pro_make; stio_dev_pro_make_t pro_make;
@ -421,6 +497,7 @@ int main ()
} }
stio_dev_pro_write (pro, "MY STIO LIBRARY\n", 16, STIO_NULL); stio_dev_pro_write (pro, "MY STIO LIBRARY\n", 16, STIO_NULL);
//stio_dev_pro_killchild (pro);
//stio_dev_pro_close (pro, STIO_DEV_PRO_IN); //stio_dev_pro_close (pro, STIO_DEV_PRO_IN);
//stio_dev_pro_close (pro, STIO_DEV_PRO_OUT); //stio_dev_pro_close (pro, STIO_DEV_PRO_OUT);
//stio_dev_pro_close (pro, STIO_DEV_PRO_ERR); //stio_dev_pro_close (pro, STIO_DEV_PRO_ERR);
@ -430,11 +507,17 @@ int main ()
g_stio = STIO_NULL; g_stio = STIO_NULL;
stio_close (stio); stio_close (stio);
#if defined(USE_SSL)
cleanup_openssl ();
#endif
return 0; return 0;
oops: oops:
g_stio = STIO_NULL; g_stio = STIO_NULL;
stio_close (stio); stio_close (stio);
#if defined(USE_SSL)
cleanup_openssl ();
#endif
return -1; return -1;
} }

View File

@ -610,11 +610,25 @@ static int dev_pro_ioctl (stio_dev_t* dev, int cmd, void* arg)
* initiated by the slave device itself. */ * initiated by the slave device itself. */
stio_killdev (rdev->stio, (stio_dev_t*)rdev->slave[sid]); stio_killdev (rdev->stio, (stio_dev_t*)rdev->slave[sid]);
} }
break; return 0;
} }
}
return 0; case STIO_DEV_PRO_KILL_CHILD:
if (rdev->child_pid >= 0)
{
if (kill (rdev->child_pid, SIGKILL) == -1)
{
rdev->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
}
return 0;
default:
dev->stio->errnum = STIO_EINVAL;
return -1;
}
} }
static stio_dev_mth_t dev_pro_methods = static stio_dev_mth_t dev_pro_methods =
@ -801,12 +815,16 @@ int stio_dev_pro_timedwrite (stio_dev_pro_t* dev, const void* data, stio_iolen_t
} }
} }
int stio_dev_pro_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid) int stio_dev_pro_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid)
{ {
return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_PRO_CLOSE, &sid); return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_PRO_CLOSE, &sid);
} }
int stio_dev_pro_killchild (stio_dev_pro_t* dev)
{
return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_PRO_KILL_CHILD, STIO_NULL);
}
#if 0 #if 0
stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_sid_t sid) stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_sid_t sid)
{ {

View File

@ -58,8 +58,6 @@ struct stio_dev_pro_t
stio_dev_pro_on_write_t on_write; stio_dev_pro_on_write_t on_write;
stio_dev_pro_on_close_t on_close; stio_dev_pro_on_close_t on_close;
stio_tmridx_t tmridx_connect;
stio_mchar_t* mcmd; stio_mchar_t* mcmd;
}; };
@ -115,7 +113,8 @@ struct stio_dev_pro_make_t
enum stio_dev_pro_ioctl_cmd_t enum stio_dev_pro_ioctl_cmd_t
{ {
STIO_DEV_PRO_CLOSE STIO_DEV_PRO_CLOSE,
STIO_DEV_PRO_KILL_CHILD
}; };
typedef enum stio_dev_pro_ioctl_cmd_t stio_dev_pro_ioctl_cmd_t; typedef enum stio_dev_pro_ioctl_cmd_t stio_dev_pro_ioctl_cmd_t;
@ -153,6 +152,11 @@ STIO_EXPORT int stio_dev_pro_close (
stio_dev_pro_sid_t sid stio_dev_pro_sid_t sid
); );
STIO_EXPORT int stio_dev_pro_killchild (
stio_dev_pro_t* pro
);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -62,13 +62,13 @@ struct stio_t
{ {
stio_dev_t* head; stio_dev_t* head;
stio_dev_t* tail; stio_dev_t* tail;
} dev; /* normal devices */ } actdev; /* active devices */
struct struct
{ {
stio_dev_t* head; stio_dev_t* head;
stio_dev_t* tail; stio_dev_t* tail;
} hdev; /* halted devices */ } hltdev; /* halted devices */
struct struct
{ {

View File

@ -37,6 +37,22 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netpacket/packet.h> #include <netpacket/packet.h>
#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
# include <openssl/ssl.h>
# if defined(HAVE_OPENSSL_ERR_H)
# include <openssl/err.h>
# endif
# if defined(HAVE_OPENSSL_ENGINE_H)
# include <openssl/engine.h>
# endif
# define USE_SSL
#endif
#if defined(USE_SSL)
# define HANDLE_TO_SSL(x) ((SSL*)(x))
# define SSL_TO_HANDLE(x) ((qse_httpd_hnd_t)(x))
#endif
/* ========================================================================= */ /* ========================================================================= */
void stio_closeasyncsck (stio_t* stio, stio_sckhnd_t sck) void stio_closeasyncsck (stio_t* stio, stio_sckhnd_t sck)
{ {
@ -298,6 +314,14 @@ static int dev_sck_kill (stio_dev_t* dev, int force)
rdev->sck = STIO_SCKHND_INVALID; rdev->sck = STIO_SCKHND_INVALID;
} }
#if defined(USE_SSL)
if (rdev->secure_ctx)
{
SSL_CTX_free ((SSL_CTX*)rdev->secure_ctx);
rdev->secure_ctx = STIO_NULL;
}
#endif
return 0; return 0;
} }
@ -416,6 +440,9 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
stio_scklen_t sl; stio_scklen_t sl;
stio_sckfam_t fam; stio_sckfam_t fam;
int x; int x;
#if defined(USE_SSL)
SSL_CTX* ssl = STIO_NULL;
#endif
if (bnd->options & STIO_DEV_SCK_BIND_BROADCAST) if (bnd->options & STIO_DEV_SCK_BIND_BROADCAST)
{ {
@ -437,16 +464,49 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
} }
} }
if (bnd->options & STIO_DEV_SCK_BIND_SECURE)
{
#if defined(USE_SSL)
SSL_CTX* ssl;
ssl = SSL_CTX_new (SSLv23_server_method());
if (!ssl)
{
rdev->stio->errnum = STIO_ESYSERR;
return -1;
}
if (SSL_CTX_use_certificate_file (ssl, bnd->certfile, SSL_FILETYPE_PEM) == 0 ||
SSL_CTX_use_PrivateKey_file (ssl, bnd->keyfile, SSL_FILETYPE_PEM) == 0 ||
SSL_CTX_check_private_key (ssl) == 0)
{
rdev->stio->errnum = STIO_ESYSERR;
SSL_CTX_free (ssl);
return -1;
}
SSL_CTX_set_read_ahead (ssl, 0);
#else
rdev->stio->errnum = STIO_ENOIMPL;
return -1;
#endif
}
if (stio_getsckadrinfo (dev->stio, &bnd->addr, &sl, &fam) <= -1) return -1; if (stio_getsckadrinfo (dev->stio, &bnd->addr, &sl, &fam) <= -1) return -1;
/* the socket is already non-blocking */
x = bind (rdev->sck, sa, sl); x = bind (rdev->sck, sa, sl);
if (x == -1) if (x == -1)
{ {
rdev->stio->errnum = stio_syserrtoerrnum(errno); rdev->stio->errnum = stio_syserrtoerrnum(errno);
#if defined(USE_SSL)
if (ssl) SSL_CTX_free (ssl);
#endif
return -1; return -1;
} }
#if defined(USE_SSL)
rdev->secure_ctx = ssl;
#endif
return 0; return 0;
} }
@ -651,11 +711,7 @@ static int dev_evcb_sck_ready_stateful (stio_dev_t* dev, int events)
STIO_ASSERT (rdev->tmridx_connect == STIO_TMRIDX_INVALID); STIO_ASSERT (rdev->tmridx_connect == STIO_TMRIDX_INVALID);
} }
if (rdev->on_connect (rdev) <= -1) if (rdev->on_connect (rdev) <= -1) return -1;
{
printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n");
return -1;
}
} }
else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK) else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK)
{ {

View File

@ -145,8 +145,10 @@ struct stio_dev_sck_make_t
enum stio_dev_sck_bind_option_t enum stio_dev_sck_bind_option_t
{ {
STIO_DEV_SCK_BIND_BROADCAST = (1 << 0), STIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
STIO_DEV_SCK_BIND_REUSEADDR = (1 << 1) STIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
/* TODO: more options --- TRANSPARENT...SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */ /* TODO: more options --- TRANSPARENT...SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
STIO_DEV_SCK_BIND_SECURE = (1 << 15)
}; };
typedef enum stio_dev_sck_bind_option_t stio_dev_sck_bind_option_t; typedef enum stio_dev_sck_bind_option_t stio_dev_sck_bind_option_t;
@ -156,6 +158,9 @@ struct stio_dev_sck_bind_t
int options; int options;
stio_sckadr_t addr; stio_sckadr_t addr;
/* TODO: add device name for BIND_TO_DEVICE */ /* TODO: add device name for BIND_TO_DEVICE */
const stio_mchar_t* certfile;
const stio_mchar_t* keyfile;
}; };
typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t; typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t;
@ -189,6 +194,7 @@ struct stio_dev_sck_t
stio_dev_sck_type_t type; stio_dev_sck_type_t type;
stio_sckhnd_t sck; stio_sckhnd_t sck;
void* secure_ctx;
stio_dev_sck_on_write_t on_write; stio_dev_sck_on_write_t on_write;
stio_dev_sck_on_read_t on_read; stio_dev_sck_on_read_t on_read;
@ -241,7 +247,6 @@ STIO_EXPORT int stio_getsckadrinfo (
); );
void stio_sckadr_initforip4 ( void stio_sckadr_initforip4 (
stio_sckadr_t* sckadr, stio_sckadr_t* sckadr,
stio_uint16_t port, stio_uint16_t port,

View File

@ -38,6 +38,21 @@
static int schedule_kill_zombie_job (stio_dev_t* dev); static int schedule_kill_zombie_job (stio_dev_t* dev);
static int kill_and_free_device (stio_dev_t* dev, int force); static int kill_and_free_device (stio_dev_t* dev, int force);
#define APPEND_DEVICE_TO_LIST(list,dev) do { \
if ((list)->tail) (list)->tail->dev_next = (dev); \
else (list)->head = (dev); \
(dev)->dev_prev = (list)->tail; \
(dev)->dev_next = STIO_NULL; \
(list)->tail = (dev); \
} while(0)
#define UNLINK_DEVICE_FROM_LIST(list,dev) do { \
if ((dev)->dev_prev) (dev)->dev_prev->dev_next = (dev)->dev_next; \
else (list)->head = (dev)->dev_next; \
if ((dev)->dev_next) (dev)->dev_next->dev_prev = (dev)->dev_prev; \
else (list)->tail = (dev)->dev_prev; \
} while (0)
stio_t* stio_open (stio_mmgr_t* mmgr, stio_size_t xtnsize, stio_size_t tmrcapa, stio_errnum_t* errnum) stio_t* stio_open (stio_mmgr_t* mmgr, stio_size_t xtnsize, stio_size_t tmrcapa, stio_errnum_t* errnum)
{ {
stio_t* stio; stio_t* stio;
@ -96,39 +111,61 @@ int stio_init (stio_t* stio, stio_mmgr_t* mmgr, stio_size_t tmrcapa)
void stio_fini (stio_t* stio) void stio_fini (stio_t* stio)
{ {
stio_dev_t* dev; stio_dev_t* dev, * next_dev;
struct
/* purge scheduled timer jobs and kill the timer */ {
stio_cleartmrjobs (stio); stio_dev_t* head;
STIO_MMGR_FREE (stio->mmgr, stio->tmr.jobs); stio_dev_t* tail;
} diehard;
/* kill all registered devices */ /* kill all registered devices */
while (stio->dev.head) while (stio->actdev.head)
{ {
stio_killdev (stio, stio->dev.head); stio_killdev (stio, stio->actdev.head);
} }
while (stio->hdev.head) while (stio->hltdev.head)
{ {
stio_killdev (stio, stio->hdev.head); stio_killdev (stio, stio->hltdev.head);
} }
/* clean up all zombie devices */ /* clean up all zombie devices */
STIO_MEMSET (&diehard, 0, STIO_SIZEOF(diehard));
for (dev = stio->zmbdev.head; dev; ) for (dev = stio->zmbdev.head; dev; )
{ {
kill_and_free_device (dev, 1); kill_and_free_device (dev, 1);
if (stio->zmbdev.head == dev) dev = dev->dev_next; if (stio->zmbdev.head == dev)
{
/* the deive has not been freed. go on to the next one */
next_dev = dev->dev_next;
/* remove the device from the zombie device list */
UNLINK_DEVICE_FROM_LIST (&stio->zmbdev, dev);
dev->dev_capa &= ~STIO_DEV_CAPA_ZOMBIE;
/* put it to a private list for aborting */
APPEND_DEVICE_TO_LIST (&diehard, dev);
dev = next_dev;
}
else dev = stio->zmbdev.head; else dev = stio->zmbdev.head;
} }
while (stio->zmbdev.tail) while (diehard.head)
{ {
/* if the kill method returns failure, it can leak some resource /* if the kill method returns failure, it can leak some resource
* because the device is freed regardless of the failure when 2 * because the device is freed regardless of the failure when 2
* is given to kill_and_free_device(). */ * is given to kill_and_free_device(). */
kill_and_free_device (stio->zmbdev.tail, 2); dev = diehard.head;
STIO_ASSERT (!(dev->dev_capa & (STIO_DEV_CAPA_ACTIVE | STIO_DEV_CAPA_HALTED | STIO_DEV_CAPA_ZOMBIE)));
UNLINK_DEVICE_FROM_LIST (&diehard, dev);
kill_and_free_device (dev, 2);
} }
/* purge scheduled timer jobs and kill the timer */
stio_cleartmrjobs (stio);
STIO_MMGR_FREE (stio->mmgr, stio->tmr.jobs);
/* close the multiplexer */ /* close the multiplexer */
close (stio->mux); close (stio->mux);
} }
@ -416,7 +453,7 @@ static STIO_INLINE int __exec (stio_t* stio)
int nentries, i; int nentries, i;
#endif #endif
/*if (!stio->dev.head) return 0;*/ /*if (!stio->actdev.head) return 0;*/
/* execute the scheduled jobs before checking devices with the /* execute the scheduled jobs before checking devices with the
* multiplexer. the scheduled jobs can safely destroy the devices */ * multiplexer. the scheduled jobs can safely destroy the devices */
@ -460,12 +497,12 @@ static STIO_INLINE int __exec (stio_t* stio)
} }
/* kill all halted devices */ /* kill all halted devices */
while (stio->hdev.head) while (stio->hltdev.head)
{ {
printf ("KILLING HALTED DEVICE %p\n", stio->hdev.head); printf (">>>>>>>>>>>>>> KILLING HALTED DEVICE %p\n", stio->hltdev.head);
stio_killdev (stio, stio->hdev.head); stio_killdev (stio, stio->hltdev.head);
} }
STIO_ASSERT (stio->hdev.tail == STIO_NULL); STIO_ASSERT (stio->hltdev.tail == STIO_NULL);
#endif #endif
@ -490,14 +527,14 @@ void stio_stop (stio_t* stio)
int stio_loop (stio_t* stio) int stio_loop (stio_t* stio)
{ {
if (!stio->dev.head) return 0; if (!stio->actdev.head) return 0;
stio->stopreq = 0; stio->stopreq = 0;
stio->renew_watch = 0; stio->renew_watch = 0;
if (stio_prologue (stio) <= -1) return -1; if (stio_prologue (stio) <= -1) return -1;
while (!stio->stopreq && stio->dev.head) while (!stio->stopreq && stio->actdev.head)
{ {
if (stio_exec (stio) <= -1) break; if (stio_exec (stio) <= -1) break;
/* you can do other things here */ /* you can do other things here */
@ -563,11 +600,9 @@ stio_dev_t* stio_makedev (stio_t* stio, stio_size_t dev_size, stio_dev_mth_t* de
if (stio_dev_watch (dev, STIO_DEV_WATCH_START, 0) <= -1) goto oops_after_make; if (stio_dev_watch (dev, STIO_DEV_WATCH_START, 0) <= -1) goto oops_after_make;
#endif #endif
/* and place the new dev at the back */ /* and place the new device object at the back of the active device list */
if (stio->dev.tail) stio->dev.tail->dev_next = dev; APPEND_DEVICE_TO_LIST (&stio->actdev, dev);
else stio->dev.head = dev; dev->dev_capa |= STIO_DEV_CAPA_ACTIVE;
dev->dev_prev = stio->dev.tail;
stio->dev.tail = dev;
return dev; return dev;
@ -607,6 +642,9 @@ static int kill_and_free_device (stio_dev_t* dev, int force)
{ {
stio_t* stio; stio_t* stio;
STIO_ASSERT (!(dev->dev_capa & STIO_DEV_CAPA_ACTIVE));
STIO_ASSERT (!(dev->dev_capa & STIO_DEV_CAPA_HALTED));
stio = dev->stio; stio = dev->stio;
if (dev->dev_mth->kill(dev, force) <= -1) if (dev->dev_mth->kill(dev, force) <= -1)
@ -615,14 +653,8 @@ static int kill_and_free_device (stio_dev_t* dev, int force)
if (!(dev->dev_capa & STIO_DEV_CAPA_ZOMBIE)) if (!(dev->dev_capa & STIO_DEV_CAPA_ZOMBIE))
{ {
APPEND_DEVICE_TO_LIST (&stio->zmbdev, dev);
dev->dev_capa |= STIO_DEV_CAPA_ZOMBIE; dev->dev_capa |= STIO_DEV_CAPA_ZOMBIE;
/* place it at the back of the zombie device list */
if (stio->hdev.tail) stio->hdev.tail->dev_next = dev;
else stio->zmbdev.head = dev;
dev->dev_prev = stio->hdev.tail;
dev->dev_next = STIO_NULL;
stio->zmbdev.tail = dev;
} }
return -1; return -1;
@ -632,15 +664,8 @@ free_device:
if (dev->dev_capa & STIO_DEV_CAPA_ZOMBIE) if (dev->dev_capa & STIO_DEV_CAPA_ZOMBIE)
{ {
/* detach it from the zombie device list */ /* detach it from the zombie device list */
if (dev->dev_prev) UNLINK_DEVICE_FROM_LIST (&stio->zmbdev, dev);
dev->dev_prev->dev_next = dev->dev_next; dev->dev_capa &= ~STIO_DEV_CAPA_ZOMBIE;
else
stio->zmbdev.head = dev->dev_next;
if (dev->dev_next)
dev->dev_next->dev_prev = dev->dev_prev;
else
stio->zmbdev.tail = dev->dev_prev;
} }
STIO_MMGR_FREE (stio->mmgr, dev); STIO_MMGR_FREE (stio->mmgr, dev);
@ -709,34 +734,18 @@ void stio_killdev (stio_t* stio, stio_dev_t* dev)
STIO_MMGR_FREE (stio->mmgr, q); STIO_MMGR_FREE (stio->mmgr, q);
} }
/* delink the dev object */
if (dev->dev_capa & STIO_DEV_CAPA_HALTED) if (dev->dev_capa & STIO_DEV_CAPA_HALTED)
{ {
/* this device is in the halted state. /* this device is in the halted state.
* unlink it from the halted device list */ * unlink it from the halted device list */
if (dev->dev_prev) UNLINK_DEVICE_FROM_LIST (&stio->hltdev, dev);
dev->dev_prev->dev_next = dev->dev_next; dev->dev_capa &= ~STIO_DEV_CAPA_HALTED;
else
stio->hdev.head = dev->dev_next;
if (dev->dev_next)
dev->dev_next->dev_prev = dev->dev_prev;
else
stio->hdev.tail = dev->dev_prev;
} }
else else
{ {
/* this device has not been halted. STIO_ASSERT (dev->dev_capa & STIO_DEV_CAPA_ACTIVE);
* unlink it from the normal active device list */ UNLINK_DEVICE_FROM_LIST (&stio->actdev, dev);
if (dev->dev_prev) dev->dev_capa &= ~STIO_DEV_CAPA_ACTIVE;
dev->dev_prev->dev_next = dev->dev_next;
else
stio->dev.head = dev->dev_next;
if (dev->dev_next)
dev->dev_next->dev_prev = dev->dev_prev;
else
stio->dev.tail = dev->dev_prev;
} }
stio_dev_watch (dev, STIO_DEV_WATCH_STOP, 0); stio_dev_watch (dev, STIO_DEV_WATCH_STOP, 0);
@ -765,29 +774,18 @@ kill_device:
void stio_dev_halt (stio_dev_t* dev) void stio_dev_halt (stio_dev_t* dev)
{ {
if (!(dev->dev_capa & (STIO_DEV_CAPA_HALTED | STIO_DEV_CAPA_ZOMBIE))) if (dev->dev_capa & STIO_DEV_CAPA_ACTIVE)
{ {
stio_t* stio; stio_t* stio;
stio = dev->stio; stio = dev->stio;
/* delink the dev object from the device list */ /* delink the device object from the active device list */
if (dev->dev_prev) UNLINK_DEVICE_FROM_LIST (&stio->actdev, dev);
dev->dev_prev->dev_next = dev->dev_next; dev->dev_capa &= ~STIO_DEV_CAPA_ACTIVE;
else
stio->dev.head = dev->dev_next;
if (dev->dev_next)
dev->dev_next->dev_prev = dev->dev_prev;
else
stio->dev.tail = dev->dev_prev;
/* place it at the back of the halted device list */ /* place it at the back of the halted device list */
if (stio->hdev.tail) stio->hdev.tail->dev_next = dev; APPEND_DEVICE_TO_LIST (&stio->hltdev, dev);
else stio->hdev.head = dev;
dev->dev_prev = stio->hdev.tail;
dev->dev_next = STIO_NULL;
stio->hdev.tail = dev;
dev->dev_capa |= STIO_DEV_CAPA_HALTED; dev->dev_capa |= STIO_DEV_CAPA_HALTED;
} }
} }
@ -826,6 +824,7 @@ int stio_dev_watch (stio_dev_t* dev, stio_dev_watch_cmd_t cmd, int events)
* data for writing. */ * data for writing. */
events = STIO_DEV_EVENT_IN; events = STIO_DEV_EVENT_IN;
if (!STIO_WQ_ISEMPTY(&dev->wq)) events |= STIO_DEV_EVENT_OUT; if (!STIO_WQ_ISEMPTY(&dev->wq)) events |= STIO_DEV_EVENT_OUT;
/* fall through */
case STIO_DEV_WATCH_UPDATE: case STIO_DEV_WATCH_UPDATE:
/* honor event watching requests as given by the caller */ /* honor event watching requests as given by the caller */
epoll_op = EPOLL_CTL_MOD; epoll_op = EPOLL_CTL_MOD;

View File

@ -106,7 +106,6 @@ enum stio_errnum_t
STIO_ECONRS, /* connection reset */ STIO_ECONRS, /* connection reset */
STIO_ENOCAPA, /* no capability */ STIO_ENOCAPA, /* no capability */
STIO_ETMOUT, /* timed out */ STIO_ETMOUT, /* timed out */
STIO_EDEVMAKE, STIO_EDEVMAKE,
STIO_EDEVERR, STIO_EDEVERR,
@ -273,8 +272,9 @@ enum stio_dev_capa_t
STIO_DEV_CAPA_OUT_WATCHED = (1 << 13), STIO_DEV_CAPA_OUT_WATCHED = (1 << 13),
STIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if STIO_DEV_CAPA_IN_WATCHED is set */ STIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if STIO_DEV_CAPA_IN_WATCHED is set */
STIO_DEV_CAPA_HALTED = (1 << 15), STIO_DEV_CAPA_ACTIVE = (1 << 15),
STIO_DEV_CAPA_ZOMBIE = (1 << 16) STIO_DEV_CAPA_HALTED = (1 << 16),
STIO_DEV_CAPA_ZOMBIE = (1 << 17)
}; };
typedef enum stio_dev_capa_t stio_dev_capa_t; typedef enum stio_dev_capa_t stio_dev_capa_t;