From 3ca7bcd549c8caf149be5a7b08303e6af85a8e69 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 17 Apr 2016 17:00:58 +0000 Subject: [PATCH] enhanced zombie device handling and improved the process pipe device --- stio/lib/Makefile.am | 2 +- stio/lib/Makefile.in | 4 +- stio/lib/main.c | 85 +++++++++++++++++++++++- stio/lib/stio-pro.c | 26 ++++++-- stio/lib/stio-pro.h | 10 ++- stio/lib/stio-prv.h | 4 +- stio/lib/stio-sck.c | 68 +++++++++++++++++-- stio/lib/stio-sck.h | 9 ++- stio/lib/stio.c | 153 +++++++++++++++++++++---------------------- stio/lib/stio.h | 6 +- 10 files changed, 266 insertions(+), 101 deletions(-) diff --git a/stio/lib/Makefile.am b/stio/lib/Makefile.am index 8239fa3..898fd8d 100644 --- a/stio/lib/Makefile.am +++ b/stio/lib/Makefile.am @@ -36,7 +36,7 @@ libstio_la_SOURCES = \ stio-tmr.c libstio_la_CPPFLAGS = $(CPPFLAGS_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 stio_SOURCES = main.c diff --git a/stio/lib/Makefile.in b/stio/lib/Makefile.in index 178f532..0426766 100644 --- a/stio/lib/Makefile.in +++ b/stio/lib/Makefile.in @@ -102,7 +102,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ LTLIBRARIES = $(lib_LTLIBRARIES) 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 \ libstio_la-stio-sck.lo libstio_la-stio-tim.lo \ libstio_la-stio-tmr.lo @@ -342,7 +342,7 @@ libstio_la_SOURCES = \ libstio_la_CPPFLAGS = $(CPPFLAGS_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_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) stio_LDFLAGS = $(LDFLAGS_LIB_COMMON) diff --git a/stio/lib/main.c b/stio/lib/main.c index 082221e..0aa6fcf 100644 --- a/stio/lib/main.c +++ b/stio/lib/main.c @@ -40,6 +40,17 @@ #include #include +#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL) +# include +# if defined(HAVE_OPENSSL_ERR_H) +# include +# endif +# if defined(HAVE_OPENSSL_ENGINE_H) +# include +# endif +# define USE_SSL +#endif + /* ========================================================================= */ 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 { int tally; @@ -243,10 +270,11 @@ static void handle_signal (int sig) int main () { + int i; stio_t* stio; stio_dev_sck_t* sck; - stio_dev_sck_t* tcp[2]; + stio_dev_sck_t* tcp[3]; struct sigaction sigact; stio_dev_sck_connect_t tcp_conn; @@ -257,6 +285,11 @@ int main () stio_dev_sck_make_t sck_make; tcp_server_t* ts; +#if defined(USE_SSL) + SSL_load_error_strings (); + SSL_library_init (); +#endif + stio = stio_open (&mmgr, 0, 512, STIO_NULL); if (!stio) { @@ -322,10 +355,13 @@ int main () 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[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make); if (!tcp[1]) { @@ -337,6 +373,45 @@ int main () memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind)); 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) { @@ -400,6 +475,7 @@ int main () #endif +for (i = 0; i < 5; i++) { stio_dev_pro_t* pro; 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_killchild (pro); //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_ERR); @@ -430,11 +507,17 @@ int main () g_stio = STIO_NULL; stio_close (stio); +#if defined(USE_SSL) + cleanup_openssl (); +#endif return 0; oops: g_stio = STIO_NULL; stio_close (stio); +#if defined(USE_SSL) + cleanup_openssl (); +#endif return -1; } diff --git a/stio/lib/stio-pro.c b/stio/lib/stio-pro.c index 0681077..516d8c9 100644 --- a/stio/lib/stio-pro.c +++ b/stio/lib/stio-pro.c @@ -610,11 +610,25 @@ static int dev_pro_ioctl (stio_dev_t* dev, int cmd, void* arg) * initiated by the slave device itself. */ 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 = @@ -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) { 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 stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_sid_t sid) { diff --git a/stio/lib/stio-pro.h b/stio/lib/stio-pro.h index 5c5a250..ca89c02 100644 --- a/stio/lib/stio-pro.h +++ b/stio/lib/stio-pro.h @@ -58,8 +58,6 @@ struct stio_dev_pro_t stio_dev_pro_on_write_t on_write; stio_dev_pro_on_close_t on_close; - stio_tmridx_t tmridx_connect; - stio_mchar_t* mcmd; }; @@ -115,7 +113,8 @@ struct stio_dev_pro_make_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; @@ -153,6 +152,11 @@ STIO_EXPORT int stio_dev_pro_close ( stio_dev_pro_sid_t sid ); + +STIO_EXPORT int stio_dev_pro_killchild ( + stio_dev_pro_t* pro +); + #ifdef __cplusplus } #endif diff --git a/stio/lib/stio-prv.h b/stio/lib/stio-prv.h index 1a5abfb..6a23c5b 100644 --- a/stio/lib/stio-prv.h +++ b/stio/lib/stio-prv.h @@ -62,13 +62,13 @@ struct stio_t { stio_dev_t* head; stio_dev_t* tail; - } dev; /* normal devices */ + } actdev; /* active devices */ struct { stio_dev_t* head; stio_dev_t* tail; - } hdev; /* halted devices */ + } hltdev; /* halted devices */ struct { diff --git a/stio/lib/stio-sck.c b/stio/lib/stio-sck.c index 2b874ec..f0ea330 100644 --- a/stio/lib/stio-sck.c +++ b/stio/lib/stio-sck.c @@ -37,6 +37,22 @@ #include #include +#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL) +# include +# if defined(HAVE_OPENSSL_ERR_H) +# include +# endif +# if defined(HAVE_OPENSSL_ENGINE_H) +# include +# 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) { @@ -298,6 +314,14 @@ static int dev_sck_kill (stio_dev_t* dev, int force) 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; } @@ -416,6 +440,9 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg) stio_scklen_t sl; stio_sckfam_t fam; int x; + #if defined(USE_SSL) + SSL_CTX* ssl = STIO_NULL; + #endif 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; - /* the socket is already non-blocking */ x = bind (rdev->sck, sa, sl); if (x == -1) { rdev->stio->errnum = stio_syserrtoerrnum(errno); + #if defined(USE_SSL) + if (ssl) SSL_CTX_free (ssl); + #endif return -1; } + #if defined(USE_SSL) + rdev->secure_ctx = ssl; + #endif 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); } - if (rdev->on_connect (rdev) <= -1) - { - printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n"); - return -1; - } + if (rdev->on_connect (rdev) <= -1) return -1; } else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK) { diff --git a/stio/lib/stio-sck.h b/stio/lib/stio-sck.h index f8538ff..fbf7b07 100644 --- a/stio/lib/stio-sck.h +++ b/stio/lib/stio-sck.h @@ -145,8 +145,10 @@ struct stio_dev_sck_make_t enum stio_dev_sck_bind_option_t { 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 */ + + STIO_DEV_SCK_BIND_SECURE = (1 << 15) }; 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; stio_sckadr_t addr; /* 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; @@ -189,6 +194,7 @@ struct stio_dev_sck_t stio_dev_sck_type_t type; stio_sckhnd_t sck; + void* secure_ctx; stio_dev_sck_on_write_t on_write; stio_dev_sck_on_read_t on_read; @@ -241,7 +247,6 @@ STIO_EXPORT int stio_getsckadrinfo ( ); - void stio_sckadr_initforip4 ( stio_sckadr_t* sckadr, stio_uint16_t port, diff --git a/stio/lib/stio.c b/stio/lib/stio.c index 21d8880..c705d3a 100644 --- a/stio/lib/stio.c +++ b/stio/lib/stio.c @@ -38,6 +38,21 @@ static int schedule_kill_zombie_job (stio_dev_t* dev); 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; @@ -96,39 +111,61 @@ int stio_init (stio_t* stio, stio_mmgr_t* mmgr, stio_size_t tmrcapa) void stio_fini (stio_t* stio) { - stio_dev_t* dev; - - /* purge scheduled timer jobs and kill the timer */ - stio_cleartmrjobs (stio); - STIO_MMGR_FREE (stio->mmgr, stio->tmr.jobs); + stio_dev_t* dev, * next_dev; + struct + { + stio_dev_t* head; + stio_dev_t* tail; + } diehard; /* 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 */ + STIO_MEMSET (&diehard, 0, STIO_SIZEOF(diehard)); for (dev = stio->zmbdev.head; dev; ) { 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; } - while (stio->zmbdev.tail) + while (diehard.head) { /* if the kill method returns failure, it can leak some resource * because the device is freed regardless of the failure when 2 * 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 (stio->mux); } @@ -416,7 +453,7 @@ static STIO_INLINE int __exec (stio_t* stio) int nentries, i; #endif - /*if (!stio->dev.head) return 0;*/ + /*if (!stio->actdev.head) return 0;*/ /* execute the scheduled jobs before checking devices with the * 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 */ - while (stio->hdev.head) + while (stio->hltdev.head) { -printf ("KILLING HALTED DEVICE %p\n", stio->hdev.head); - stio_killdev (stio, stio->hdev.head); +printf (">>>>>>>>>>>>>> KILLING HALTED DEVICE %p\n", stio->hltdev.head); + stio_killdev (stio, stio->hltdev.head); } - STIO_ASSERT (stio->hdev.tail == STIO_NULL); + STIO_ASSERT (stio->hltdev.tail == STIO_NULL); #endif @@ -490,14 +527,14 @@ void stio_stop (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->renew_watch = 0; 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; /* 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; #endif - /* and place the new dev at the back */ - if (stio->dev.tail) stio->dev.tail->dev_next = dev; - else stio->dev.head = dev; - dev->dev_prev = stio->dev.tail; - stio->dev.tail = dev; + /* and place the new device object at the back of the active device list */ + APPEND_DEVICE_TO_LIST (&stio->actdev, dev); + dev->dev_capa |= STIO_DEV_CAPA_ACTIVE; return dev; @@ -607,6 +642,9 @@ static int kill_and_free_device (stio_dev_t* dev, int force) { stio_t* stio; + STIO_ASSERT (!(dev->dev_capa & STIO_DEV_CAPA_ACTIVE)); + STIO_ASSERT (!(dev->dev_capa & STIO_DEV_CAPA_HALTED)); + stio = dev->stio; 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)) { + APPEND_DEVICE_TO_LIST (&stio->zmbdev, dev); 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; @@ -632,15 +664,8 @@ free_device: if (dev->dev_capa & STIO_DEV_CAPA_ZOMBIE) { /* detach it from the zombie device list */ - if (dev->dev_prev) - dev->dev_prev->dev_next = dev->dev_next; - 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; + UNLINK_DEVICE_FROM_LIST (&stio->zmbdev, dev); + dev->dev_capa &= ~STIO_DEV_CAPA_ZOMBIE; } 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); } - /* delink the dev object */ if (dev->dev_capa & STIO_DEV_CAPA_HALTED) { /* this device is in the halted state. * unlink it from the halted device list */ - if (dev->dev_prev) - dev->dev_prev->dev_next = dev->dev_next; - 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; + UNLINK_DEVICE_FROM_LIST (&stio->hltdev, dev); + dev->dev_capa &= ~STIO_DEV_CAPA_HALTED; } else { - /* this device has not been halted. - * unlink it from the normal active device list */ - if (dev->dev_prev) - 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_ASSERT (dev->dev_capa & STIO_DEV_CAPA_ACTIVE); + UNLINK_DEVICE_FROM_LIST (&stio->actdev, dev); + dev->dev_capa &= ~STIO_DEV_CAPA_ACTIVE; } stio_dev_watch (dev, STIO_DEV_WATCH_STOP, 0); @@ -765,29 +774,18 @@ kill_device: 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 = dev->stio; - /* delink the dev object from the device list */ - if (dev->dev_prev) - 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; + /* delink the device object from the active device list */ + UNLINK_DEVICE_FROM_LIST (&stio->actdev, dev); + dev->dev_capa &= ~STIO_DEV_CAPA_ACTIVE; /* place it at the back of the halted device list */ - if (stio->hdev.tail) stio->hdev.tail->dev_next = dev; - else stio->hdev.head = dev; - dev->dev_prev = stio->hdev.tail; - dev->dev_next = STIO_NULL; - stio->hdev.tail = dev; - + APPEND_DEVICE_TO_LIST (&stio->hltdev, dev); 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. */ events = STIO_DEV_EVENT_IN; if (!STIO_WQ_ISEMPTY(&dev->wq)) events |= STIO_DEV_EVENT_OUT; + /* fall through */ case STIO_DEV_WATCH_UPDATE: /* honor event watching requests as given by the caller */ epoll_op = EPOLL_CTL_MOD; diff --git a/stio/lib/stio.h b/stio/lib/stio.h index 3c93c8e..f7c7c1f 100644 --- a/stio/lib/stio.h +++ b/stio/lib/stio.h @@ -106,7 +106,6 @@ enum stio_errnum_t STIO_ECONRS, /* connection reset */ STIO_ENOCAPA, /* no capability */ STIO_ETMOUT, /* timed out */ - STIO_EDEVMAKE, STIO_EDEVERR, @@ -273,8 +272,9 @@ enum stio_dev_capa_t 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_HALTED = (1 << 15), - STIO_DEV_CAPA_ZOMBIE = (1 << 16) + STIO_DEV_CAPA_ACTIVE = (1 << 15), + STIO_DEV_CAPA_HALTED = (1 << 16), + STIO_DEV_CAPA_ZOMBIE = (1 << 17) }; typedef enum stio_dev_capa_t stio_dev_capa_t;