enhanced zombie device handling and improved the process pipe device
This commit is contained in:
		@ -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
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,17 @@
 | 
			
		||||
#include <netpacket/packet.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
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,22 @@
 | 
			
		||||
#include <arpa/inet.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)
 | 
			
		||||
{
 | 
			
		||||
@ -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)
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user