enhanced zombie device handling and improved the process pipe device
This commit is contained in:
parent
8b5a5bbc4f
commit
3ca7bcd549
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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,
|
||||||
|
153
stio/lib/stio.c
153
stio/lib/stio.c
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user