unfinished refactoring

This commit is contained in:
hyung-hwan 2019-01-27 02:09:22 +00:00
parent 276d15877d
commit 446809d7f4
23 changed files with 1070 additions and 695 deletions

12
mio/configure vendored
View File

@ -17969,6 +17969,18 @@ _ACEOF
fi
done
for ac_func in isatty mmap munmap
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"

View File

@ -161,6 +161,7 @@ AC_CHECK_FUNCS([fork vfork posix_spawn gettid nanosleep select])
AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext])
AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf])
AC_CHECK_FUNCS([accept4 sendmsg recvmsg writev readv])
AC_CHECK_FUNCS([isatty mmap munmap])
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"

View File

@ -1,2 +0,0 @@
all:
cc -g -I. -Wall -o mio main.c mio.c mio-tcp.c mio-udp.c mio-sck.c

View File

@ -30,19 +30,20 @@ include_HEADERS = \
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
err.c \
logfmt.c \
logfmtv.h \
fmtout.c \
fmtoutv.h \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
sck-addr.c \
sck-addr.h \
sys-ass.c \
sys-err.c \
sys-log.c \
sys-mux.c \
sys-tim.c \
tmr.c \
utf8.c \
utl.c
libmio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)

View File

@ -140,11 +140,11 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am_libmio_la_OBJECTS = libmio_la-err.lo libmio_la-logfmt.lo \
am_libmio_la_OBJECTS = libmio_la-err.lo libmio_la-fmtout.lo \
libmio_la-mio.lo libmio_la-mio-pro.lo libmio_la-mio-sck.lo \
libmio_la-mio-tim.lo libmio_la-mio-tmr.lo \
libmio_la-sck-addr.lo libmio_la-sys-ass.lo \
libmio_la-sys-err.lo libmio_la-sys-log.lo libmio_la-utf8.lo \
libmio_la-sys-err.lo libmio_la-sys-log.lo libmio_la-sys-mux.lo \
libmio_la-sys-tim.lo libmio_la-tmr.lo libmio_la-utf8.lo \
libmio_la-utl.lo
libmio_la_OBJECTS = $(am_libmio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@ -403,19 +403,20 @@ include_HEADERS = \
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
err.c \
logfmt.c \
logfmtv.h \
fmtout.c \
fmtoutv.h \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
sck-addr.c \
sck-addr.h \
sys-ass.c \
sys-err.c \
sys-log.c \
sys-mux.c \
sys-tim.c \
tmr.c \
utf8.c \
utl.c
@ -574,16 +575,17 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-logfmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-fmtout.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-pro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tim.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sck-addr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-ass.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-log.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-mux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sys-tim.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-utf8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mio-main.Po@am__quote@
@ -619,12 +621,12 @@ libmio_la-err.lo: err.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-err.lo `test -f 'err.c' || echo '$(srcdir)/'`err.c
libmio_la-logfmt.lo: logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-logfmt.lo -MD -MP -MF $(DEPDIR)/libmio_la-logfmt.Tpo -c -o libmio_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-logfmt.Tpo $(DEPDIR)/libmio_la-logfmt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logfmt.c' object='libmio_la-logfmt.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-fmtout.lo: fmtout.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-fmtout.lo -MD -MP -MF $(DEPDIR)/libmio_la-fmtout.Tpo -c -o libmio_la-fmtout.lo `test -f 'fmtout.c' || echo '$(srcdir)/'`fmtout.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-fmtout.Tpo $(DEPDIR)/libmio_la-fmtout.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fmtout.c' object='libmio_la-fmtout.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-fmtout.lo `test -f 'fmtout.c' || echo '$(srcdir)/'`fmtout.c
libmio_la-mio.lo: mio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio.Tpo -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
@ -647,20 +649,6 @@ libmio_la-mio-sck.lo: mio-sck.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-sck.lo `test -f 'mio-sck.c' || echo '$(srcdir)/'`mio-sck.c
libmio_la-mio-tim.lo: mio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-tim.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-tim.Tpo -c -o libmio_la-mio-tim.lo `test -f 'mio-tim.c' || echo '$(srcdir)/'`mio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-tim.Tpo $(DEPDIR)/libmio_la-mio-tim.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-tim.c' object='libmio_la-mio-tim.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-tim.lo `test -f 'mio-tim.c' || echo '$(srcdir)/'`mio-tim.c
libmio_la-mio-tmr.lo: mio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-tmr.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-tmr.Tpo -c -o libmio_la-mio-tmr.lo `test -f 'mio-tmr.c' || echo '$(srcdir)/'`mio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-tmr.Tpo $(DEPDIR)/libmio_la-mio-tmr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-tmr.c' object='libmio_la-mio-tmr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-tmr.lo `test -f 'mio-tmr.c' || echo '$(srcdir)/'`mio-tmr.c
libmio_la-sck-addr.lo: sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sck-addr.lo -MD -MP -MF $(DEPDIR)/libmio_la-sck-addr.Tpo -c -o libmio_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sck-addr.Tpo $(DEPDIR)/libmio_la-sck-addr.Plo
@ -689,6 +677,27 @@ libmio_la-sys-log.lo: sys-log.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sys-log.lo `test -f 'sys-log.c' || echo '$(srcdir)/'`sys-log.c
libmio_la-sys-mux.lo: sys-mux.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sys-mux.lo -MD -MP -MF $(DEPDIR)/libmio_la-sys-mux.Tpo -c -o libmio_la-sys-mux.lo `test -f 'sys-mux.c' || echo '$(srcdir)/'`sys-mux.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sys-mux.Tpo $(DEPDIR)/libmio_la-sys-mux.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-mux.c' object='libmio_la-sys-mux.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sys-mux.lo `test -f 'sys-mux.c' || echo '$(srcdir)/'`sys-mux.c
libmio_la-sys-tim.lo: sys-tim.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sys-tim.lo -MD -MP -MF $(DEPDIR)/libmio_la-sys-tim.Tpo -c -o libmio_la-sys-tim.lo `test -f 'sys-tim.c' || echo '$(srcdir)/'`sys-tim.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sys-tim.Tpo $(DEPDIR)/libmio_la-sys-tim.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-tim.c' object='libmio_la-sys-tim.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sys-tim.lo `test -f 'sys-tim.c' || echo '$(srcdir)/'`sys-tim.c
libmio_la-tmr.lo: tmr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-tmr.lo -MD -MP -MF $(DEPDIR)/libmio_la-tmr.Tpo -c -o libmio_la-tmr.lo `test -f 'tmr.c' || echo '$(srcdir)/'`tmr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-tmr.Tpo $(DEPDIR)/libmio_la-tmr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tmr.c' object='libmio_la-tmr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-tmr.lo `test -f 'tmr.c' || echo '$(srcdir)/'`tmr.c
libmio_la-utf8.lo: utf8.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-utf8.lo -MD -MP -MF $(DEPDIR)/libmio_la-utf8.Tpo -c -o libmio_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-utf8.Tpo $(DEPDIR)/libmio_la-utf8.Plo

View File

@ -26,6 +26,7 @@
#include "mio-prv.h"
/* TODO: this table is wrong. the messages are wrong as of now. fix these... */
static mio_ooch_t errstr_0[] = {'n','o',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_1[] = {'g','e','n','e','r','i','c',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_2[] = {'n','o','t',' ','i','m','p','l','e','m','e','n','t','e','d','\0'};

View File

@ -142,8 +142,8 @@ typedef int (*mio_fmtout_putcs_t) (
mio_oow_t len
);
typedef struct mio_fmtout_t mio_fmtout_t;
struct mio_fmtout_t
typedef struct mio_fmtout_data_t mio_fmtout_data_t;
struct mio_fmtout_data_t
{
mio_oow_t count; /* out */
mio_bitmask_t mask; /* in */
@ -381,44 +381,44 @@ redo:
#undef FMTCHAR_IS_UCH
#undef FMTCHAR_IS_OOCH
#undef fmtchar_t
#undef logfmtv
#undef fmtoutv
#define fmtchar_t mio_bch_t
#define logfmtv __logbfmtv
#define fmtoutv __logbfmtv
#define FMTCHAR_IS_BCH
#if defined(MIO_OOCH_IS_BCH)
# define FMTCHAR_IS_OOCH
#endif
#include "logfmtv.h"
#include "fmtoutv.h"
#undef FMTCHAR_IS_BCH
#undef FMTCHAR_IS_UCH
#undef FMTCHAR_IS_OOCH
#undef fmtchar_t
#undef logfmtv
#undef fmtoutv
#define fmtchar_t mio_uch_t
#define logfmtv __logufmtv
#define fmtoutv __logufmtv
#define FMTCHAR_IS_UCH
#if defined(MIO_OOCH_IS_UCH)
# define FMTCHAR_IS_OOCH
#endif
#include "logfmtv.h"
#include "fmtoutv.h"
static int _logbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _logbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, mio_logbfmt);
return __logbfmtv(mio, fmt, data, ap);
}
static int _logufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _logufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, mio_logbfmt);
return __logufmtv(mio, fmt, data, ap);
}
mio_ooi_t mio_logbfmt (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->log.default_type_mask & MIO_LOG_ALL_TYPES)
{
@ -451,7 +451,7 @@ mio_ooi_t mio_logufmt (mio_t* mio, mio_bitmask_t mask, const mio_uch_t* fmt, ...
{
int x;
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->log.default_type_mask & MIO_LOG_ALL_TYPES)
{
@ -519,36 +519,20 @@ static int put_errcs (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* ptr, mio
static mio_ooi_t __errbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _errbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _errbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, __errbfmtv);
return __logbfmtv (mio, fmt, data, ap);
}
static int _errufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _errufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, __errbfmtv);
}
static mio_ooi_t __errbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
va_start (ap, fmt);
_errbfmtv (mio, fmt, &fo, ap);
va_end (ap);
return fo.count;
return __logufmtv (mio, fmt, data, ap);
}
void mio_seterrbfmt (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
@ -567,7 +551,7 @@ void mio_seterrbfmt (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, ...)
void mio_seterrufmt (mio_t* mio, mio_errnum_t errnum, const mio_uch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
@ -586,7 +570,7 @@ void mio_seterrufmt (mio_t* mio, mio_errnum_t errnum, const mio_uch_t* fmt, ...)
void mio_seterrbfmtv (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, va_list ap)
{
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->shuterr) return;
@ -602,7 +586,7 @@ void mio_seterrbfmtv (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, va_
void mio_seterrufmtv (mio_t* mio, mio_errnum_t errnum, const mio_uch_t* fmt, va_list ap)
{
mio_fmtout_t fo;
mio_fmtout_data_t fo;
if (mio->shuterr) return;
@ -669,38 +653,22 @@ static int put_sprch (mio_t* mio, mio_bitmask_t mask, mio_ooch_t ch, mio_oow_t l
static mio_ooi_t __sprbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _sprbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _sprbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, __sprbfmtv);
return __logbfmtv (mio, fmt, data, ap);
}
/*
static int _sprufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
static int _sprufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, __sprbfmtv);
}*/
static mio_ooi_t __sprbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
fo.mask = mask; /* not used */
fo.putch = put_sprch;
fo.putcs = put_sprcs;
va_start (ap, fmt);
_sprbfmtv (mio, fmt, &fo, ap);
va_end (ap);
return fo.count;
}
mio_ooi_t mio_sproutbfmt (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
fo.mask = mask;
fo.putch = put_sprch;
@ -718,7 +686,7 @@ mio_ooi_t mio_sproutufmt (mio_t* mio, mio_bitmask_t mask, const mio_uch_t* fmt,
{
int x;
va_list ap;
mio_fmtout_t fo;
mio_fmtout_data_t fo;
fo.mask = mask;
fo.putch = put_sprch;

View File

@ -74,7 +74,7 @@
#define PUT_OOCH(c,n) do { \
if (n > 0) { \
int xx; \
if ((xx = data->putch (mio, data->mask, c, n)) <= -1) goto oops; \
if ((xx = data->putch(mio, data->mask, c, n)) <= -1) goto oops; \
if (xx == 0) goto done; \
data->count += n; \
} \
@ -83,13 +83,13 @@
#define PUT_OOCS(ptr,len) do { \
if (len > 0) { \
int xx; \
if ((xx = data->putcs (mio, data->mask, ptr, len)) <= -1) goto oops; \
if ((xx = data->putcs(mio, data->mask, ptr, len)) <= -1) goto oops; \
if (xx == 0) goto done; \
data->count += len; \
} \
} while (0)
static int logfmtv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_t* data, va_list ap, outbfmt_t outbfmt)
static int fmtoutv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
const fmtchar_t* percent;
const fmtchar_t* checkpoint;
@ -584,10 +584,6 @@ static int logfmtv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_t* data, va_lis
break;
}
case 'O': /* object - ignore precision, width, adjustment */
if (print_object(mio, data->mask, va_arg(ap, mio_oop_t), outbfmt) <= -1) goto oops;
break;
#if 0
case 'e':
case 'E':

View File

@ -206,7 +206,7 @@ else
// if (ts->tally >= 2) mio_dev_sck_halt (tcp);
printf ("TCP_SCK_ON_WRITE ENABLING READING..............................\n");
mio_inittime (&tmout, 5, 0);
MIO_INIT_NTIME (&tmout, 5, 0);
//mio_dev_sck_read (tcp, 1);
mio_dev_sck_timedread (tcp, 1, &tmout);
}
@ -243,7 +243,7 @@ memset (xxx, a++ ,1000000);
printf ("TCP_SCK_ON_READ initiating write... of %d\n", 1000000);
//return mio_dev_sck_write (tcp, "HELLO", 5, MIO_NULL);
mio_inittime (&tmout, 5, 0);
MIO_INIT_NTIME (&tmout, 5, 0);
n = mio_dev_sck_timedwrite (tcp, xxx, 1000000, &tmout, MIO_NULL, MIO_NULL);
free (xxx);
@ -439,12 +439,12 @@ static int schedule_icmp_wait (mio_dev_sck_t* dev)
mio_ntime_t fire_after;
icmpxtn = (icmpxtn_t*)(dev + 1);
mio_inittime (&fire_after, 2, 0);
MIO_INIT_NTIME (&fire_after, 2, 0);
memset (&tmrjob, 0, MIO_SIZEOF(tmrjob));
tmrjob.ctx = dev;
mio_gettime (&tmrjob.when);
mio_addtime (&tmrjob.when, &fire_after, &tmrjob.when);
mio_sys_gettime (&tmrjob.when);
MIO_ADD_NTIME (&tmrjob.when, &tmrjob.when, &fire_after);
tmrjob.handler = on_icmp_due;
tmrjob.idxptr = &icmpxtn->tmout_jobidx;
@ -554,7 +554,7 @@ static int setup_ping4_tester (mio_t* mio)
/* ========================================================================= */
#if 1
#if 0
static mio_t* g_mio;
static void handle_signal (int sig)
@ -641,7 +641,7 @@ int main (int argc, char* argv[])
mio_sckaddr_initforip4 (&tcp_conn.remoteaddr, 9999, (mio_ip4addr_t*)&ia);
}
mio_inittime (&tcp_conn.connect_tmout, 5, 0);
MIO_INIT_NTIME (&tcp_conn.connect_tmout, 5, 0);
tcp_conn.options = MIO_DEV_SCK_CONNECT_SSL;
if (mio_dev_sck_connect(tcp[0], &tcp_conn) <= -1)
{
@ -706,7 +706,7 @@ int main (int argc, char* argv[])
tcp_bind.options = MIO_DEV_SCK_BIND_REUSEADDR | /*MIO_DEV_SCK_BIND_REUSEPORT |*/ MIO_DEV_SCK_BIND_SSL;
tcp_bind.ssl_certfile = "localhost.crt";
tcp_bind.ssl_keyfile = "localhost.key";
mio_inittime (&tcp_bind.accept_tmout, 5, 1);
MIO_INIT_NTIME (&tcp_bind.accept_tmout, 5, 1);
if (mio_dev_sck_bind(tcp[2], &tcp_bind) <= -1)
{
@ -782,7 +782,7 @@ int main (int argc, char* argv[])
mio_dev_sck_connect_t tcp_conn;
tcp_server_t* ts;
mio = mio_open(&mmgr, 0, 512, MIO_NULL);
mio = mio_open(&mmgr, 0, MIO_NULL, 512, MIO_NULL);
if (!mio)
{
printf ("Cannot open mio\n");
@ -810,7 +810,7 @@ int main (int argc, char* argv[])
in_addr_t ia = inet_addr("127.0.0.1");
mio_sckaddr_initforip4 (&tcp_conn.remoteaddr, 9999, (mio_ip4addr_t*)&ia);
}
mio_inittime (&tcp_conn.connect_tmout, 5, 0);
MIO_INIT_NTIME (&tcp_conn.connect_tmout, 5, 0);
tcp_conn.options = 0;
if (mio_dev_sck_connect(tcpsvr, &tcp_conn) <= -1)
{

View File

@ -250,6 +250,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `isatty' function. */
#undef HAVE_ISATTY
/* Define to 1 if you have the `isblank' function. */
#undef HAVE_ISBLANK
@ -334,6 +337,12 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define to 1 if you have the `munmap' function. */
#undef HAVE_MUNMAP
/* Define to 1 if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP

View File

@ -433,6 +433,13 @@ struct mio_ntime_t
#define MIO_CMP_NTIME(a,b) (((a)->sec == (b)->sec)? ((a)->nsec - (b)->nsec): ((a)->sec - (b)->sec))
/* if time has been normalized properly, nsec must be equal to or
* greater than 0. */
#define MIO_IS_NEG_NTIME(x) ((x)->sec < 0)
#define MIO_IS_POS_NTIME(x) ((x)->sec > 0 || ((x)->sec == 0 && (x)->nsec > 0))
#define MIO_IS_ZERO_NTIME(x) ((x)->sec == 0 && (x)->nsec == 0)
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */

View File

@ -137,7 +137,7 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
pid = fork ();
if (pid == -1)
{
mio->errnum = mio_syserrtoerrnum(errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -234,7 +234,7 @@ static int dev_pro_make_master (mio_dev_t* dev, void* ctx)
{
if (pipe(&pfds[0]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
dev->mio_seterrwithsyserr (mio, 0, errno);
goto oops;
}
minidx = 0; maxidx = 1;
@ -244,7 +244,7 @@ static int dev_pro_make_master (mio_dev_t* dev, void* ctx)
{
if (pipe(&pfds[2]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
dev->mio_seterrwithsyserr (mio, 0, errno);
goto oops;
}
if (minidx == -1) minidx = 2;
@ -255,7 +255,7 @@ static int dev_pro_make_master (mio_dev_t* dev, void* ctx)
{
if (pipe(&pfds[4]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
dev->mio_seterrwithsyserr (mio, 0, errno);
goto oops;
}
if (minidx == -1) minidx = 4;
@ -508,7 +508,7 @@ static int dev_pro_kill_slave (mio_dev_t* dev, int force)
/* indicate EOF */
if (master->on_close) master->on_close (master, rdev->id);
MIO_ASSERT (master->slave_count > 0);
MIO_ASSERT (dev->mio, master->slave_count > 0);
master->slave_count--;
if (master->slave[rdev->id])
@ -550,7 +550,7 @@ static int dev_pro_read_slave (mio_dev_t* dev, void* buf, mio_iolen_t* len, mio_
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
pro->mio->errnum = mio_syserrtoerrnum(errno);
pro->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -568,7 +568,7 @@ static int dev_pro_write_slave (mio_dev_t* dev, const void* data, mio_iolen_t* l
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
pro->mio->errnum = mio_syserrtoerrnum(errno);
pro->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -618,7 +618,7 @@ static int dev_pro_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
if (kill (rdev->child_pid, SIGKILL) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
}

View File

@ -51,25 +51,6 @@
#endif
#define MIO_EPOCH_YEAR (1970)
#define MIO_EPOCH_MON (1)
#define MIO_EPOCH_DAY (1)
#define MIO_EPOCH_WDAY (4)
/* windows specific epoch time */
#define MIO_EPOCH_YEAR_WIN (1601)
#define MIO_EPOCH_MON_WIN (1)
#define MIO_EPOCH_DAY_WIN (1)
#define MIO_DAYS_PER_WEEK (7)
#define MIO_MONS_PER_YEAR (12)
#define MIO_HOURS_PER_DAY (24)
#define MIO_MINS_PER_HOUR (60)
#define MIO_MINS_PER_DAY (MIO_MINS_PER_HOUR*MIO_HOURS_PER_DAY)
#define MIO_SECS_PER_MIN (60)
#define MIO_SECS_PER_HOUR (MIO_SECS_PER_MIN*MIO_MINS_PER_HOUR)
#define MIO_SECS_PER_DAY (MIO_SECS_PER_MIN*MIO_MINS_PER_DAY)
/* i don't want an error raised inside the callback to override
* the existing error number and message. */
#define prim_write_log(mio,mask,ptr,len) do { \
@ -88,10 +69,6 @@ int mio_makesyshndasync (
mio_syshnd_t hnd
);
mio_errnum_t mio_syserrtoerrnum (
int no
);
mio_bch_t* mio_mbsdup (
mio_t* mio,
@ -137,6 +114,26 @@ int mio_gettmrtmout (
mio_ntime_t* tmout
);
/* ========================================================================= */
/* err.c */
/* ========================================================================= */
void mio_seterrbfmtv (
mio_t* mio,
mio_errnum_t errnum,
const mio_bch_t* fmt,
va_list ap
);
void mio_seterrufmtv (
mio_t* mio,
mio_errnum_t errnum,
const mio_uch_t* fmt,
va_list ap
);
/* ========================================================================== */
/* system intefaces */
/* ========================================================================== */
void mio_sys_assertfail (
mio_t* mio,
@ -153,6 +150,16 @@ mio_errnum_t mio_sys_syserrstrb (
mio_oow_t len
);
void mio_sys_initlog (
mio_t* mio
);
void mio_sys_finilog (
mio_t* mio
);
void mio_sys_writelog (
mio_t* mio,
mio_bitmask_t mask,
@ -160,6 +167,29 @@ void mio_sys_writelog (
mio_oow_t len
);
int mio_sys_initmux (
mio_t* mio
);
void mio_sys_finimux (
mio_t* mio
);
int mio_sys_ctrlmux (
mio_t* mio,
mio_sys_mux_cmd_t cmd,
mio_dev_t* dev,
int dev_capa
);
/**
* The mio_sys_gettime() function gets the current time.
*/
void mio_sys_gettime (
mio_ntime_t* nt
);
#ifdef __cplusplus
}
#endif

View File

@ -129,7 +129,7 @@ done:
oops:
if (sck != MIO_SCKHND_INVALID) close (sck);
mio->errnum = mio_syserrtoerrnum(errno);
mio_seterrwithsyserr (mio, 0, errno);
return MIO_SCKHND_INVALID;
}
@ -345,7 +345,7 @@ static void connect_timedout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t*
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)job->ctx;
MIO_ASSERT (IS_STATEFUL(rdev));
MIO_ASSERT (mio, IS_STATEFUL(rdev));
if (rdev->state & MIO_DEV_SCK_CONNECTING)
{
@ -362,7 +362,7 @@ static void ssl_accept_timedout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)job->ctx;
MIO_ASSERT (IS_STATEFUL(rdev));
MIO_ASSERT (mio, IS_STATEFUL(rdev));
if (rdev->state & MIO_DEV_SCK_ACCEPTING_SSL)
{
@ -374,7 +374,7 @@ static void ssl_connect_timedout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)job->ctx;
MIO_ASSERT (IS_STATEFUL(rdev));
MIO_ASSERT (mio, IS_STATEFUL(rdev));
if (rdev->state & MIO_DEV_SCK_CONNECTING_SSL)
{
@ -393,7 +393,7 @@ static int schedule_timer_job_at (mio_dev_sck_t* dev, const mio_ntime_t* fire_at
tmrjob.handler = handler;
tmrjob.idxptr = &dev->tmrjob_index;
MIO_ASSERT (dev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (dev->mio, dev->tmrjob_index == MIO_TMRIDX_INVALID);
dev->tmrjob_index = mio_instmrjob (dev->mio, &tmrjob);
return dev->tmrjob_index == MIO_TMRIDX_INVALID? -1: 0;
}
@ -402,10 +402,10 @@ static int schedule_timer_job_after (mio_dev_sck_t* dev, const mio_ntime_t* fire
{
mio_ntime_t fire_at;
MIO_ASSERT (mio_ispostime(fire_after));
MIO_ASSERT (dev->mio, MIO_IS_POS_NTIME(fire_after));
mio_gettime (&fire_at);
mio_addtime (&fire_at, fire_after, &fire_at);
mio_sys_gettime (&fire_at);
MIO_ADD_NTIME (&fire_at, &fire_at, fire_after);
return schedule_timer_job_at (dev, &fire_at, handler);
}
@ -417,7 +417,7 @@ static int dev_sck_make (mio_dev_t* dev, void* ctx)
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_dev_sck_make_t* arg = (mio_dev_sck_make_t*)ctx;
MIO_ASSERT (arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map));
MIO_ASSERT (dev->mio, arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map));
if (sck_type_map[arg->type].domain <= -1)
{
@ -467,7 +467,7 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
int flags = fcntl(rdev->sck, F_GETFD, 0);
if (fcntl(rdev->sck, F_SETFD, flags | FD_CLOEXEC) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
}
@ -492,13 +492,13 @@ static int dev_sck_kill (mio_dev_t* dev, int force)
if (rdev->tmrjob_index != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (dev->mio, rdev->tmrjob_index);
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (dev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
}
}
else
{
MIO_ASSERT (rdev->state == 0);
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (dev->mio, rdev->state == 0);
MIO_ASSERT (dev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
if (rdev->on_disconnect) rdev->on_disconnect (rdev);
}
@ -562,7 +562,7 @@ static int dev_sck_read_stateful (mio_dev_t* dev, void* buf, mio_iolen_t* len, m
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -585,7 +585,7 @@ static int dev_sck_read_stateless (mio_dev_t* dev, void* buf, mio_iolen_t* len,
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -642,7 +642,7 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
* the socket, probably leaving it in the half-closed state */
if (shutdown(rdev->sck, SHUT_WR) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -658,7 +658,7 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -679,7 +679,7 @@ static int dev_sck_write_stateless (mio_dev_t* dev, const void* data, mio_iolen_
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -772,6 +772,7 @@ static MIO_INLINE int accept_ssl (mio_dev_sck_t* dev)
static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_t* mio = dev->mio;
switch (cmd)
{
@ -797,7 +798,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_BROADCAST, &v, MIO_SIZEOF(v)) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
}
@ -808,7 +809,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEADDR, &v, MIO_SIZEOF(v)) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
#else
@ -823,7 +824,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEPORT, &v, MIO_SIZEOF(v)) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
#else
@ -838,7 +839,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
int v = 1;
if (setsockopt(rdev->sck, SOL_IP, IP_TRANSPARENT, &v, MIO_SIZEOF(v)) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
#else
@ -849,12 +850,16 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
if (rdev->ssl_ctx)
{
#if defined(USE_SSL)
SSL_CTX_free (rdev->ssl_ctx);
#endif
rdev->ssl_ctx = MIO_NULL;
if (rdev->ssl)
{
#if defined(USE_SSL)
SSL_free (rdev->ssl);
#endif
rdev->ssl = MIO_NULL;
}
}
@ -904,7 +909,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
x = bind(rdev->sck, sa, sl);
if (x == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
#if defined(USE_SSL)
if (ssl_ctx) SSL_CTX_free (ssl_ctx);
#endif
@ -1003,9 +1008,9 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
}
else
{
mio_inittime (&rdev->tmout, 0, 0); /* just in case */
MIO_INIT_NTIME (&rdev->tmout, 0, 0); /* just in case */
if (mio_ispostime(&conn->connect_tmout))
if (MIO_IS_POS_NTIME(&conn->connect_tmout))
{
if (schedule_timer_job_after(rdev, &conn->connect_tmout, connect_timedout) <= -1)
{
@ -1014,7 +1019,7 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
else
{
/* update rdev->tmout to the deadline of the connect timeout job */
MIO_ASSERT (rdev->tmrjob_index != MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, rdev->tmrjob_index != MIO_TMRIDX_INVALID);
mio_gettmrjobdeadline (rdev->mio, rdev->tmrjob_index, &rdev->tmout);
}
}
@ -1028,7 +1033,7 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
}
}
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
oops_connect:
if (mio_dev_watch((mio_dev_t*)rdev, MIO_DEV_WATCH_UPDATE, MIO_DEV_EVENT_IN) <= -1)
@ -1068,11 +1073,11 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
if (x == 0)
{
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
mio_inittime (&rdev->tmout, 0, 0); /* just in case */
MIO_INIT_NTIME (&rdev->tmout, 0, 0); /* just in case */
/* it's ok to use conn->connect_tmout for ssl-connect as
* the underlying socket connection has been established immediately */
if (mio_ispostime(&conn->connect_tmout))
if (MIO_IS_POS_NTIME(&conn->connect_tmout))
{
if (schedule_timer_job_after(rdev, &conn->connect_tmout, ssl_connect_timedout) <= -1)
{
@ -1134,7 +1139,7 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
x = listen (rdev->sck, lstn->backlogs);
if (x == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1186,12 +1191,12 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
int errcode;
mio_scklen_t len;
MIO_ASSERT (!(rdev->state & MIO_DEV_SCK_CONNECTED));
MIO_ASSERT (rdev->mio, !(rdev->state & MIO_DEV_SCK_CONNECTED));
len = MIO_SIZEOF(errcode);
if (getsockopt(rdev->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
else if (errcode == 0)
@ -1204,7 +1209,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
if (rdev->tmrjob_index != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (rdev->mio, rdev->tmrjob_index);
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (rdev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
}
addrlen = MIO_SIZEOF(localaddr);
@ -1235,7 +1240,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
/* rdev->tmout has been set to the deadline of the connect task
* when the CONNECT IOCTL command has been executed. use the
* same deadline here */
if (mio_ispostime(&rdev->tmout) &&
if (MIO_IS_POS_NTIME(&rdev->tmout) &&
schedule_timer_job_at(rdev, &rdev->tmout, ssl_connect_timedout) <= -1)
{
mio_dev_halt ((mio_dev_t*)rdev);
@ -1267,13 +1272,14 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
}
else
{
rdev->mio->errnum = mio_syserrtoerrnum(errcode);
mio_seterrwithsyserr (rdev->mio, 0, errcode);
return -1;
}
}
static int accept_incoming_connection (mio_dev_sck_t* rdev)
{
mio_t* mio = rdev->mio;
mio_sckhnd_t clisck;
mio_sckaddr_t remoteaddr;
mio_scklen_t addrlen;
@ -1294,7 +1300,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1313,7 +1319,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
rdev->mio->errnum = mio_syserrtoerrnum(errno);
rdev->mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1330,7 +1336,7 @@ accept_done:
return -1;
}
MIO_ASSERT (clidev->sck == clisck);
MIO_ASSERT (mio, clidev->sck == clisck);
clidev->dev_capa |= MIO_DEV_CAPA_IN | MIO_DEV_CAPA_OUT | MIO_DEV_CAPA_STREAM | MIO_DEV_CAPA_OUT_QUEUED;
clidev->remoteaddr = remoteaddr;
@ -1382,18 +1388,18 @@ accept_done:
clidev->on_write = rdev->on_write;
clidev->on_read = rdev->on_read;
MIO_ASSERT (clidev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, clidev->tmrjob_index == MIO_TMRIDX_INVALID);
if (rdev->ssl_ctx)
{
MIO_DEV_SCK_SET_PROGRESS (clidev, MIO_DEV_SCK_ACCEPTING_SSL);
MIO_ASSERT (clidev->state & MIO_DEV_SCK_ACCEPTING_SSL);
MIO_ASSERT (mio, clidev->state & MIO_DEV_SCK_ACCEPTING_SSL);
/* actual SSL acceptance must be completed in the client device */
/* let the client device know the SSL context to use */
clidev->ssl_ctx = rdev->ssl_ctx;
if (mio_ispostime(&rdev->tmout) &&
if (MIO_IS_POS_NTIME(&rdev->tmout) &&
schedule_timer_job_after (clidev, &rdev->tmout, ssl_accept_timedout) <= -1)
{
/* TODO: call a warning/error callback */
@ -1431,7 +1437,7 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
}
else
{
rdev->mio->errnum = mio_syserrtoerrnum (errcode);
mio_seterrwithsyserr (rdev->mio, 0, errcode);
}
return -1;
}
@ -1605,7 +1611,7 @@ static int dev_evcb_sck_ready_stateless (mio_dev_t* dev, int events)
}
else
{
rdev->mio->errnum = mio_syserrtoerrnum (errcode);
mio_seterrwithsyserr (rdev->mio, 0, errcode);
}
return -1;
}

View File

@ -26,20 +26,6 @@
#include "mio-prv.h"
#if defined(HAVE_SYS_EPOLL_H)
# include <sys/epoll.h>
# define USE_EPOLL
#elif defined(HAVE_SYS_POLL_H)
# include <sys/poll.h>
# define USE_POLL
#else
# error NO SUPPORTED MULTIPLEXER
#endif
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define DEV_CAPA_ALL_WATCHED (MIO_DEV_CAPA_IN_WATCHED | MIO_DEV_CAPA_OUT_WATCHED | MIO_DEV_CAPA_PRI_WATCHED)
static int schedule_kill_zombie_job (mio_dev_t* dev);
@ -65,294 +51,28 @@ static void on_read_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* j
static void on_write_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* job);
/* ========================================================================= */
#if defined(USE_POLL)
#define MUX_CMD_INSERT 1
#define MUX_CMD_UPDATE 2
#define MUX_CMD_DELETE 3
#define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t)
struct mio_mux_t
{
struct
{
mio_oow_t* ptr;
mio_oow_t size;
mio_oow_t capa;
} map; /* handle to index */
struct
{
struct pollfd* pfd;
mio_dev_t** dptr;
mio_oow_t size;
mio_oow_t capa;
} pd; /* poll data */
};
static int mux_open (mio_t* mio)
{
mio_mux_t* mux;
mux = MIO_MMGR_ALLOC (mio->mmgr, MIO_SIZEOF(*mux));
if (!mux)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
MIO_MEMSET (mux, 0, MIO_SIZEOF(*mux));
mio->mux = mux;
return 0;
}
static void mux_close (mio_t* mio)
{
if (mio->mux)
{
MIO_MMGR_FREE (mio->mmgr, mio->mux);
mio->mux = MIO_NULL;
}
}
static int mux_control (mio_dev_t* dev, int cmd, mio_syshnd_t hnd, int dev_capa)
{
mio_t* mio;
mio_mux_t* mux;
mio_oow_t idx;
mio = dev->mio;
mux = (mio_mux_t*)mio->mux;
if (hnd >= mux->map.capa)
{
mio_oow_t new_capa;
mio_oow_t* tmp;
if (cmd != MUX_CMD_INSERT)
{
mio->errnum = MIO_ENOENT;
return -1;
}
new_capa = MIO_ALIGN_POW2((hnd + 1), 256);
tmp = MIO_MMGR_REALLOC(mio->mmgr, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp));
if (!tmp)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
for (idx = mux->map.capa; idx < new_capa; idx++)
tmp[idx] = MUX_INDEX_INVALID;
mux->map.ptr = tmp;
mux->map.capa = new_capa;
}
idx = mux->map.ptr[hnd];
if (idx != MUX_INDEX_INVALID)
{
if (cmd == MUX_CMD_INSERT)
{
mio->errnum = MIO_EEXIST;
return -1;
}
}
else
{
if (cmd != MUX_CMD_INSERT)
{
mio->errnum = MIO_ENOENT;
return -1;
}
}
switch (cmd)
{
case MUX_CMD_INSERT:
if (mux->pd.size >= mux->pd.capa)
{
mio_oow_t new_capa;
struct pollfd* tmp1;
mio_dev_t** tmp2;
new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256);
tmp1 = MIO_MMGR_REALLOC(mio->mmgr, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1));
if (!tmp1)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
tmp2 = MIO_MMGR_REALLOC (mio->mmgr, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2));
if (!tmp2)
{
MIO_MMGR_FREE (mio->mmgr, tmp1);
mio->errnum = MIO_ESYSMEM;
return -1;
}
mux->pd.pfd = tmp1;
mux->pd.dptr = tmp2;
mux->pd.capa = new_capa;
}
idx = mux->pd.size++;
mux->pd.pfd[idx].fd = hnd;
mux->pd.pfd[idx].events = 0;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN;
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT;
mux->pd.pfd[idx].revents = 0;
mux->pd.dptr[idx] = dev;
mux->map.ptr[hnd] = idx;
return 0;
case MUX_CMD_UPDATE:
MIO_ASSERT (mux->pd.dptr[idx] == dev);
mux->pd.pfd[idx].events = 0;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN;
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT;
return 0;
case MUX_CMD_DELETE:
MIO_ASSERT (mux->pd.dptr[idx] == dev);
mux->map.ptr[hnd] = MUX_INDEX_INVALID;
/* TODO: speed up deletion. allow a hole in the array.
* delay array compaction if there is a hole.
* set fd for the hole to -1 such that poll()
* ignores it. compact the array if another deletion
* is requested when there is an existing hole. */
idx++;
while (idx < mux->pd.size)
{
int fd;
mux->pd.pfd[idx - 1] = mux->pd.pfd[idx];
mux->pd.dptr[idx - 1] = mux->pd.dptr[idx];
fd = mux->pd.pfd[idx].fd;
mux->map.ptr[fd] = idx - 1;
idx++;
}
mux->pd.size--;
return 0;
default:
mio->errnum = MIO_EINVAL;
return -1;
}
}
#elif defined(USE_EPOLL)
#define MUX_CMD_INSERT EPOLL_CTL_ADD
#define MUX_CMD_UPDATE EPOLL_CTL_MOD
#define MUX_CMD_DELETE EPOLL_CTL_DEL
struct mio_mux_t
{
int hnd;
struct epoll_event revs[100]; /* TODO: is it a good size? */
};
static int mux_open (mio_t* mio)
{
mio_mux_t* mux;
mux = MIO_MMGR_ALLOC (mio->mmgr, MIO_SIZEOF(*mux));
if (!mux)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
MIO_MEMSET (mux, 0, MIO_SIZEOF(*mux));
mux->hnd = epoll_create (1000);
if (mux->hnd == -1)
{
mio->errnum = mio_syserrtoerrnum(errno);
MIO_MMGR_FREE (mio->mmgr, mux);
return -1;
}
mio->mux = mux;
return 0;
}
static void mux_close (mio_t* mio)
{
if (mio->mux)
{
close (mio->mux->hnd);
MIO_MMGR_FREE (mio->mmgr, mio->mux);
mio->mux = MIO_NULL;
}
}
static MIO_INLINE int mux_control (mio_dev_t* dev, int cmd, mio_syshnd_t hnd, int dev_capa)
{
struct epoll_event ev;
ev.data.ptr = dev;
ev.events = EPOLLHUP | EPOLLERR /*| EPOLLET*/;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED)
{
ev.events |= EPOLLIN;
#if defined(EPOLLRDHUP)
ev.events |= EPOLLRDHUP;
#endif
if (dev_capa & MIO_DEV_CAPA_PRI_WATCHED) ev.events |= EPOLLPRI;
}
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) ev.events |= EPOLLOUT;
if (epoll_ctl (dev->mio->mux->hnd, cmd, hnd, &ev) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
return -1;
}
return 0;
}
#endif
/* ========================================================================= */
mio_t* mio_open (mio_mmgr_t* mmgr, mio_oow_t xtnsize, mio_oow_t tmrcapa, mio_errnum_t* errnum)
mio_t* mio_open (mio_mmgr_t* mmgr, mio_oow_t xtnsize, mio_cmgr_t* cmgr, mio_oow_t tmrcapa, mio_errinf_t* errinfo)
{
mio_t* mio;
mio = MIO_MMGR_ALLOC (mmgr, MIO_SIZEOF(mio_t) + xtnsize);
if (!cmgr) cmgr = mio_get_utf8_cmgr();
mio = (mio_t*)MIO_MMGR_ALLOC(mmgr, MIO_SIZEOF(mio_t) + xtnsize);
if (mio)
{
if (mio_init (mio, mmgr, tmrcapa) <= -1)
if (mio_init(mio, mmgr, cmgr, tmrcapa) <= -1)
{
if (errnum) *errnum = mio->errnum;
if (errinfo) mio_geterrinf (mio, errinfo);
MIO_MMGR_FREE (mmgr, mio);
mio = MIO_NULL;
}
else MIO_MEMSET (mio + 1, 0, xtnsize);
}
else
else if (errinfo)
{
if (errnum) *errnum = MIO_ESYSMEM;
errinfo->num = MIO_ESYSMEM;
mio_copy_oocstr (errinfo->msg, MIO_COUNTOF(errinfo->msg), mio_errnum_to_errstr(MIO_ESYSMEM));
}
return mio;
@ -364,28 +84,53 @@ void mio_close (mio_t* mio)
MIO_MMGR_FREE (mio->mmgr, mio);
}
int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_oow_t tmrcapa)
int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_cmgr_t* cmgr, mio_oow_t tmrcapa)
{
int sys_log_inited = 0;
int sys_mux_inited = 0;
MIO_MEMSET (mio, 0, MIO_SIZEOF(*mio));
mio->mmgr = mmgr;
mio->cmgr = cmgr;
/* initialize data for logging support */
mio->option.log_mask = MIO_LOG_ALL_LEVELS | MIO_LOG_ALL_TYPES;
mio->log.capa = MIO_ALIGN_POW2(1, MIO_LOG_CAPA_ALIGN); /* TODO: is this a good initial size? */
/* alloate the log buffer in advance though it may get reallocated
* in put_oocs and put_ooch in fmtout.c. this is to let the logging
* routine still function despite some side-effects when
* reallocation fails */
/* +1 required for consistency with put_oocs and put_ooch in fmtout.c */
mio->log.ptr = mio_allocmem(mio, (mio->log.capa + 1) * MIO_SIZEOF(*mio->log.ptr));
if (!mio->log.ptr) goto oops;
/* inititalize the system-side logging */
mio_sys_initlog (mio);
sys_log_inited = 1;
/* intialize the multiplexer object */
if (mux_open (mio) <= -1) return -1;
if (mio_sys_initmux(mio) <= -1) goto oops;
sys_mux_inited = 0;
/* initialize the timer object */
if (tmrcapa <= 0) tmrcapa = 1;
mio->tmr.jobs = MIO_MMGR_ALLOC (mio->mmgr, tmrcapa * MIO_SIZEOF(mio_tmrjob_t));
if (!mio->tmr.jobs)
{
mio->errnum = MIO_ESYSMEM;
mux_close (mio);
return -1;
}
mio->tmr.jobs = mio_allocmem(mio, tmrcapa * MIO_SIZEOF(mio_tmrjob_t));
if (!mio->tmr.jobs) goto oops;
mio->tmr.capa = tmrcapa;
MIO_CWQ_INIT (&mio->cwq);
return 0;
oops:
if (mio->tmr.jobs) mio_freemem (mio, mio->tmr.jobs);
if (sys_mux_inited) mio_sys_finimux (mio);
if (sys_log_inited) mio_sys_finilog (mio);
if (mio->log.ptr) mio_freemem (mio, mio->log.ptr);
mio->log.capa = 0;
return -1;
}
void mio_fini (mio_t* mio)
@ -449,7 +194,7 @@ void mio_fini (mio_t* mio)
* because the device is freed regardless of the failure when 2
* is given to kill_and_free_device(). */
dev = diehard.head;
MIO_ASSERT (!(dev->dev_capa & (MIO_DEV_CAPA_ACTIVE | MIO_DEV_CAPA_HALTED | MIO_DEV_CAPA_ZOMBIE)));
MIO_ASSERT (mio, !(dev->dev_capa & (MIO_DEV_CAPA_ACTIVE | MIO_DEV_CAPA_HALTED | MIO_DEV_CAPA_ZOMBIE)));
UNLINK_DEVICE_FROM_LIST (&diehard, dev);
kill_and_free_device (dev, 2);
}
@ -458,10 +203,52 @@ void mio_fini (mio_t* mio)
mio_cleartmrjobs (mio);
MIO_MMGR_FREE (mio->mmgr, mio->tmr.jobs);
/* close the multiplexer */
mux_close (mio);
mio_sys_finimux (mio); /* close the multiplexer */
mio_sys_finilog (mio); /* close the system logger */
}
int mio_setoption (mio_t* mio, mio_option_t id, const void* value)
{
switch (id)
{
case MIO_TRAIT:
mio->option.trait = *(mio_bitmask_t*)value;
return 0;
case MIO_LOG_MASK:
mio->option.log_mask = *(mio_bitmask_t*)value;
return 0;
case MIO_LOG_MAXCAPA:
mio->option.log_maxcapa = *(mio_oow_t*)value;
return 0;
}
einval:
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
int mio_getoption (mio_t* mio, mio_option_t id, void* value)
{
switch (id)
{
case MIO_TRAIT:
*(mio_bitmask_t*)value = mio->option.trait;
return 0;
case MIO_LOG_MASK:
*(mio_bitmask_t*)value = mio->option.log_mask;
return 0;
case MIO_LOG_MAXCAPA:
*(mio_oow_t*)value = mio->option.log_maxcapa;
return 0;
};
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
int mio_prologue (mio_t* mio)
{
@ -479,7 +266,7 @@ static MIO_INLINE void unlink_wq (mio_t* mio, mio_wq_t* q)
if (q->tmridx != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (mio, q->tmridx);
MIO_ASSERT (q->tmridx == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, q->tmridx == MIO_TMRIDX_INVALID);
}
MIO_WQ_UNLINK (q);
}
@ -491,7 +278,7 @@ static MIO_INLINE void handle_event (mio_dev_t* dev, int events, int rdhup)
mio = dev->mio;
mio->renew_watch = 0;
MIO_ASSERT (mio == dev->mio);
MIO_ASSERT (mio, mio == dev->mio);
if (dev->dev_evcb->ready)
{
@ -642,8 +429,8 @@ static MIO_INLINE void handle_event (mio_dev_t* dev, int events, int rdhup)
MIO_MEMSET (&tmrjob, 0, MIO_SIZEOF(tmrjob));
tmrjob.ctx = dev;
mio_gettime (&tmrjob.when);
mio_addtime (&tmrjob.when, &dev->rtmout, &tmrjob.when);
mio_sys_gettime (&tmrjob.when);
MIO_ADD_NTIME (&tmrjob.when, &tmrjob.when, &dev->rtmout);
tmrjob.handler = on_read_timeout;
tmrjob.idxptr = &dev->rtmridx;
@ -752,12 +539,8 @@ static MIO_INLINE int __exec (mio_t* mio)
{
mio_ntime_t tmout;
#if defined(_WIN32)
ULONG nentries, i;
#else
int nentries, i;
mio_mux_t* mux;
#endif
mio_sys_mux_t* mux;
/*if (!mio->actdev.head) return 0;*/
@ -811,13 +594,13 @@ static MIO_INLINE int __exec (mio_t* mio)
*/
#elif defined(USE_POLL)
mux = (mio_mux_t*)mio->mux;
mux = (mio_sys_mux_t*)mio->sys.mux;
nentries = poll(mux->pd.pfd, mux->pd.size, MIO_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec));
if (nentries == -1)
{
if (errno == EINTR) return 0;
mio->errnum = mio_syserrtoerrnum(errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -830,7 +613,7 @@ static MIO_INLINE int __exec (mio_t* mio)
dev = mux->pd.dptr[i];
MIO_ASSERT (!(mux->pd.pfd[i].revents & POLLNVAL));
MIO_ASSERT (mio, !(mux->pd.pfd[i].revents & POLLNVAL));
if (mux->pd.pfd[i].revents & POLLIN) events |= MIO_DEV_EVENT_IN;
if (mux->pd.pfd[i].revents & POLLOUT) events |= MIO_DEV_EVENT_OUT;
if (mux->pd.pfd[i].revents & POLLPRI) events |= MIO_DEV_EVENT_PRI;
@ -843,14 +626,14 @@ static MIO_INLINE int __exec (mio_t* mio)
#elif defined(USE_EPOLL)
mux = (mio_mux_t*)mio->mux;
mux = (mio_sys_mux_t*)mio->sys.mux;
nentries = epoll_wait(mux->hnd, mux->revs, MIO_COUNTOF(mux->revs), MIO_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec));
if (nentries == -1)
{
if (errno == EINTR) return 0; /* it's actually ok */
/* other errors are critical - EBADF, EFAULT, EINVAL */
mio->errnum = mio_syserrtoerrnum(errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -882,10 +665,10 @@ static MIO_INLINE int __exec (mio_t* mio)
/* kill all halted devices */
while (mio->hltdev.head)
{
printf (">>>>>>>>>>>>>> KILLING HALTED DEVICE %p\n", mio->hltdev.head);
MIO_DEBUG1 (mio, "Killing HALTED device %p\n", mio->hltdev.head);
mio_killdev (mio, mio->hltdev.head);
}
MIO_ASSERT (mio->hltdev.tail == MIO_NULL);
MIO_ASSERT (mio, mio->hltdev.tail == MIO_NULL);
return 0;
}
@ -950,7 +733,7 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
dev->dev_capa = MIO_DEV_CAPA_IN | MIO_DEV_CAPA_OUT;
dev->dev_mth = dev_mth;
dev->dev_evcb = dev_evcb;
mio_inittime (&dev->rtmout, 0, 0);
MIO_INIT_NTIME (&dev->rtmout, 0, 0);
dev->rtmridx = MIO_TMRIDX_INVALID;
MIO_WQ_INIT (&dev->wq);
dev->cw_count = 0;
@ -964,10 +747,10 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
}
/* the make callback must not change these fields */
MIO_ASSERT (dev->dev_mth == dev_mth);
MIO_ASSERT (dev->dev_evcb == dev_evcb);
MIO_ASSERT (dev->dev_prev == MIO_NULL);
MIO_ASSERT (dev->dev_next == MIO_NULL);
MIO_ASSERT (mio, dev->dev_mth == dev_mth);
MIO_ASSERT (mio, dev->dev_evcb == dev_evcb);
MIO_ASSERT (mio, dev->dev_prev == MIO_NULL);
MIO_ASSERT (mio, dev->dev_next == MIO_NULL);
/* set some internal capability bits according to the capabilities
* removed by the device making callback for convenience sake. */
@ -1026,8 +809,8 @@ static int kill_and_free_device (mio_dev_t* dev, int force)
{
mio_t* mio;
MIO_ASSERT (!(dev->dev_capa & MIO_DEV_CAPA_ACTIVE));
MIO_ASSERT (!(dev->dev_capa & MIO_DEV_CAPA_HALTED));
MIO_ASSERT (mio, !(dev->dev_capa & MIO_DEV_CAPA_ACTIVE));
MIO_ASSERT (mio, !(dev->dev_capa & MIO_DEV_CAPA_HALTED));
mio = dev->mio;
@ -1060,7 +843,7 @@ static void kill_zombie_job_handler (mio_t* mio, const mio_ntime_t* now, mio_tmr
{
mio_dev_t* dev = (mio_dev_t*)job->ctx;
MIO_ASSERT (dev->dev_capa & MIO_DEV_CAPA_ZOMBIE);
MIO_ASSERT (mio, dev->dev_capa & MIO_DEV_CAPA_ZOMBIE);
if (kill_and_free_device(dev, 0) <= -1)
{
@ -1087,12 +870,12 @@ static int schedule_kill_zombie_job (mio_dev_t* dev)
mio_tmrjob_t kill_zombie_job;
mio_ntime_t tmout;
mio_inittime (&tmout, 3, 0); /* TODO: take it from configuration */
MIO_INIT_NTIME (&tmout, 3, 0); /* TODO: take it from configuration */
MIO_MEMSET (&kill_zombie_job, 0, MIO_SIZEOF(kill_zombie_job));
kill_zombie_job.ctx = dev;
mio_gettime (&kill_zombie_job.when);
mio_addtime (&kill_zombie_job.when, &tmout, &kill_zombie_job.when);
mio_sys_gettime (&kill_zombie_job.when);
MIO_ADD_NTIME (&kill_zombie_job.when, &kill_zombie_job.when, &tmout);
kill_zombie_job.handler = kill_zombie_job_handler;
/*kill_zombie_job.idxptr = &rdev->tmridx_kill_zombie;*/
@ -1101,13 +884,13 @@ static int schedule_kill_zombie_job (mio_dev_t* dev)
void mio_killdev (mio_t* mio, mio_dev_t* dev)
{
MIO_ASSERT (mio == dev->mio);
MIO_ASSERT (mio, mio == dev->mio);
if (dev->dev_capa & MIO_DEV_CAPA_ZOMBIE)
{
MIO_ASSERT (MIO_WQ_ISEMPTY(&dev->wq));
MIO_ASSERT (dev->cw_count == 0);
MIO_ASSERT (dev->rtmridx == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, MIO_WQ_ISEMPTY(&dev->wq));
MIO_ASSERT (mio, dev->cw_count == 0);
MIO_ASSERT (mio, dev->rtmridx == MIO_TMRIDX_INVALID);
goto kill_device;
}
@ -1152,7 +935,7 @@ void mio_killdev (mio_t* mio, mio_dev_t* dev)
}
else
{
MIO_ASSERT (dev->dev_capa & MIO_DEV_CAPA_ACTIVE);
MIO_ASSERT (mio, dev->dev_capa & MIO_DEV_CAPA_ACTIVE);
UNLINK_DEVICE_FROM_LIST (&mio->actdev, dev);
dev->dev_capa &= ~MIO_DEV_CAPA_ACTIVE;
}
@ -1162,7 +945,7 @@ void mio_killdev (mio_t* mio, mio_dev_t* dev)
kill_device:
if (kill_and_free_device(dev, 0) <= -1)
{
MIO_ASSERT (dev->dev_capa & MIO_DEV_CAPA_ZOMBIE);
MIO_ASSERT (mio, dev->dev_capa & MIO_DEV_CAPA_ZOMBIE);
if (schedule_kill_zombie_job (dev) <= -1)
{
/* i have to choice but to free up the devide by force */
@ -1223,7 +1006,7 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
case MIO_DEV_WATCH_START:
/* upon start, only input watching is requested */
events = MIO_DEV_EVENT_IN;
mux_cmd = MUX_CMD_INSERT;
mux_cmd = MIO_SYS_MUX_CMD_INSERT;
break;
case MIO_DEV_WATCH_RENEW:
@ -1235,12 +1018,12 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
/* fall through */
case MIO_DEV_WATCH_UPDATE:
/* honor event watching requests as given by the caller */
mux_cmd = MUX_CMD_UPDATE;
mux_cmd = MIO_SYS_MUX_CMD_UPDATE;
break;
case MIO_DEV_WATCH_STOP:
events = 0; /* override events */
mux_cmd = MUX_CMD_DELETE;
mux_cmd = MIO_SYS_MUX_CMD_DELETE;
break;
default:
@ -1269,13 +1052,13 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
if (dev->dev_capa & MIO_DEV_CAPA_OUT) dev_capa |= MIO_DEV_CAPA_OUT_WATCHED;
}
if (mux_cmd == MUX_CMD_UPDATE && (dev_capa & DEV_CAPA_ALL_WATCHED) == (dev->dev_capa & DEV_CAPA_ALL_WATCHED))
if (mux_cmd == MIO_SYS_MUX_CMD_UPDATE && (dev_capa & DEV_CAPA_ALL_WATCHED) == (dev->dev_capa & DEV_CAPA_ALL_WATCHED))
{
/* no change in the device capacity. skip calling epoll_ctl */
}
else
{
if (mux_control(dev, mux_cmd, dev->dev_mth->getsyshnd(dev), dev_capa) <= -1) return -1;
if (mio_sys_ctrlmux(dev->mio, mux_cmd, dev, dev_capa) <= -1) return -1;
}
dev->dev_capa = dev_capa;
@ -1292,7 +1075,7 @@ static void on_read_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* j
dev->mio->errnum = MIO_ETMOUT;
x = dev->dev_evcb->on_read(dev, MIO_NULL, -1, MIO_NULL);
MIO_ASSERT (dev->rtmridx == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, dev->rtmridx == MIO_TMRIDX_INVALID);
if (x <= -1) mio_dev_halt (dev);
}
@ -1331,14 +1114,14 @@ update_timer:
dev->rtmridx = MIO_TMRIDX_INVALID;
}
if (tmout && mio_ispostime(tmout))
if (tmout && MIO_IS_POS_NTIME(tmout))
{
mio_tmrjob_t tmrjob;
MIO_MEMSET (&tmrjob, 0, MIO_SIZEOF(tmrjob));
tmrjob.ctx = dev;
mio_gettime (&tmrjob.when);
mio_addtime (&tmrjob.when, tmout, &tmrjob.when);
mio_sys_gettime (&tmrjob.when);
MIO_ADD_NTIME (&tmrjob.when, &tmrjob.when, tmout);
tmrjob.handler = on_read_timeout;
tmrjob.idxptr = &dev->rtmridx;
@ -1401,7 +1184,7 @@ static void on_write_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t*
dev->mio->errnum = MIO_ETMOUT;
x = dev->dev_evcb->on_write(dev, -1, q->ctx, &q->dstaddr);
MIO_ASSERT (q->tmridx == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, q->tmridx == MIO_TMRIDX_INVALID);
MIO_WQ_UNLINK(q);
MIO_MMGR_FREE (mio->mmgr, q);
@ -1526,14 +1309,14 @@ enqueue_data:
q->olen = len;
MIO_MEMCPY (q->ptr, uptr, urem);
if (tmout && mio_ispostime(tmout))
if (tmout && MIO_IS_POS_NTIME(tmout))
{
mio_tmrjob_t tmrjob;
MIO_MEMSET (&tmrjob, 0, MIO_SIZEOF(tmrjob));
tmrjob.ctx = q;
mio_gettime (&tmrjob.when);
mio_addtime (&tmrjob.when, tmout, &tmrjob.when);
mio_sys_gettime (&tmrjob.when);
MIO_ADD_NTIME (&tmrjob.when, &tmrjob.when, tmout);
tmrjob.handler = on_write_timeout;
tmrjob.idxptr = &q->tmridx;
@ -1624,74 +1407,17 @@ int mio_makesyshndasync (mio_t* mio, mio_syshnd_t hnd)
if ((flags = fcntl(hnd, F_GETFL)) <= -1 ||
(flags = fcntl(hnd, F_SETFL, flags | O_NONBLOCK)) <= -1)
{
mio->errnum = mio_syserrtoerrnum (errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
return 0;
#else
mio->errnum = MIO_ENOSUP;
mio->errnum = MIO_ENOIMPL;
return -1;
#endif
}
mio_errnum_t mio_syserrtoerrnum (int no)
{
switch (no)
{
case ENOMEM:
return MIO_ESYSMEM;
case EINVAL:
return MIO_EINVAL;
case EEXIST:
return MIO_EEXIST;
case ENOENT:
return MIO_ENOENT;
case EMFILE:
return MIO_EMFILE;
#if defined(ENFILE)
case ENFILE:
return MIO_ENFILE;
#endif
#if defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
case EAGAIN:
case EWOULDBLOCK:
return MIO_EAGAIN;
#elif defined(EAGAIN)
case EAGAIN:
return MIO_EAGAIN;
#elif defined(EWOULDBLOCK)
case EWOULDBLOCK:
return MIO_EAGAIN;
#endif
#if defined(ECONNREFUSED)
case ECONNREFUSED:
return MIO_ECONRF;
#endif
#if defined(ECONNRESETD)
case ECONNRESET:
return MIO_ECONRS;
#endif
#if defined(EPERM)
case EPERM:
return MIO_EPERM;
#endif
default:
return MIO_ESYSERR;
}
}
/* -------------------------------------------------------------------------- */
void* mio_allocmem (mio_t* mio, mio_oow_t size)

View File

@ -113,6 +113,15 @@ struct mio_errinf_t
};
typedef struct mio_errinf_t mio_errinf_t;
enum mio_option_t
{
MIO_TRAIT,
MIO_LOG_MASK,
MIO_LOG_MAXCAPA
};
typedef enum mio_option_t mio_option_t;
enum mio_stopreq_t
{
MIO_STOPREQ_NONE = 0,
@ -371,11 +380,84 @@ typedef enum mio_dev_event_t mio_dev_event_t;
#define MIO_CWQFL_SIZE 16
#define MIO_CWQFL_ALIGN 16
/* ========================================================================= */
/* =========================================================================
* MIO LOGGING
* ========================================================================= */
enum mio_log_mask_t
{
MIO_LOG_DEBUG = (1u << 0),
MIO_LOG_INFO = (1u << 1),
MIO_LOG_WARN = (1u << 2),
MIO_LOG_ERROR = (1u << 3),
MIO_LOG_FATAL = (1u << 4),
MIO_LOG_UNTYPED = (1u << 6), /* only to be used by MIO_DEBUGx() and MIO_INFOx() */
MIO_LOG_CORE = (1u << 7),
MIO_LOG_DEV = (1u << 8),
MIO_LOG_TIMER = (1u << 9),
MIO_LOG_ALL_LEVELS = (MIO_LOG_DEBUG | MIO_LOG_INFO | MIO_LOG_WARN | MIO_LOG_ERROR | MIO_LOG_FATAL),
MIO_LOG_ALL_TYPES = (MIO_LOG_UNTYPED | MIO_LOG_CORE | MIO_LOG_DEV | MIO_LOG_TIMER),
MIO_LOG_STDOUT = (1u << 14), /* write log messages to stdout without timestamp. MIO_LOG_STDOUT wins over MIO_LOG_STDERR. */
MIO_LOG_STDERR = (1u << 15) /* write log messages to stderr without timestamp. */
};
typedef enum mio_log_mask_t mio_log_mask_t;
/* all bits must be set to get enabled */
#define MIO_LOG_ENABLED(mio,mask) (((mio)->option.log_mask & (mask)) == (mask))
#define MIO_LOG0(mio,mask,fmt) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt); } while(0)
#define MIO_LOG1(mio,mask,fmt,a1) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1); } while(0)
#define MIO_LOG2(mio,mask,fmt,a1,a2) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1, a2); } while(0)
#define MIO_LOG3(mio,mask,fmt,a1,a2,a3) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1, a2, a3); } while(0)
#define MIO_LOG4(mio,mask,fmt,a1,a2,a3,a4) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1, a2, a3, a4); } while(0)
#define MIO_LOG5(mio,mask,fmt,a1,a2,a3,a4,a5) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1, a2, a3, a4, a5); } while(0)
#define MIO_LOG6(mio,mask,fmt,a1,a2,a3,a4,a5,a6) do { if (MIO_LOG_ENABLED(mio,mask)) mio_logbfmt(mio, mask, fmt, a1, a2, a3, a4, a5, a6); } while(0)
#if defined(MIO_BUILD_RELEASE)
/* [NOTE]
* get rid of debugging message totally regardless of
* the log mask in the release build.
*/
# define MIO_DEBUG0(mio,fmt)
# define MIO_DEBUG1(mio,fmt,a1)
# define MIO_DEBUG2(mio,fmt,a1,a2)
# define MIO_DEBUG3(mio,fmt,a1,a2,a3)
# define MIO_DEBUG4(mio,fmt,a1,a2,a3,a4)
# define MIO_DEBUG5(mio,fmt,a1,a2,a3,a4,a5)
# define MIO_DEBUG6(mio,fmt,a1,a2,a3,a4,a5,a6)
#else
# define MIO_DEBUG0(mio,fmt) MIO_LOG0(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt)
# define MIO_DEBUG1(mio,fmt,a1) MIO_LOG1(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1)
# define MIO_DEBUG2(mio,fmt,a1,a2) MIO_LOG2(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1, a2)
# define MIO_DEBUG3(mio,fmt,a1,a2,a3) MIO_LOG3(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1, a2, a3)
# define MIO_DEBUG4(mio,fmt,a1,a2,a3,a4) MIO_LOG4(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4)
# define MIO_DEBUG5(mio,fmt,a1,a2,a3,a4,a5) MIO_LOG5(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4, a5)
# define MIO_DEBUG6(mio,fmt,a1,a2,a3,a4,a5,a6) MIO_LOG6(mio, MIO_LOG_DEBUG | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4, a5, a6)
#endif
#define MIO_INFO0(mio,fmt) MIO_LOG0(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt)
#define MIO_INFO1(mio,fmt,a1) MIO_LOG1(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1)
#define MIO_INFO2(mio,fmt,a1,a2) MIO_LOG2(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1, a2)
#define MIO_INFO3(mio,fmt,a1,a2,a3) MIO_LOG3(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1, a2, a3)
#define MIO_INFO4(mio,fmt,a1,a2,a3,a4) MIO_LOG4(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4)
#define MIO_INFO5(mio,fmt,a1,a2,a3,a4,a5) MIO_LOG5(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4, a5)
#define MIO_INFO6(mio,fmt,a1,a2,a3,a4,a5,a6) MIO_LOG6(mio, MIO_LOG_INFO | MIO_LOG_UNTYPED, fmt, a1, a2, a3, a4, a5, a6)
/* ========================================================================= */
typedef struct mio_mux_t mio_mux_t;
enum mio_sys_mux_cmd_t
{
MIO_SYS_MUX_CMD_INSERT = 0,
MIO_SYS_MUX_CMD_UPDATE = 1,
MIO_SYS_MUX_CMD_DELETE = 2
};
typedef enum mio_sys_mux_cmd_t mio_sys_mux_cmd_t;
typedef struct mio_sys_mux_t mio_sys_mux_t;
typedef struct mio_sys_log_t mio_sys_log_t;
struct mio_t
{
@ -393,9 +475,15 @@ struct mio_t
mio_ooch_t buf[MIO_ERRMSG_CAPA];
mio_oow_t len;
} errmsg;
int shuterr;
mio_stopreq_t stopreq; /* stop request to abort mio_loop() */
struct
{
mio_bitmask_t trait;
mio_bitmask_t log_mask;
mio_oow_t log_maxcapa;
} option;
struct
{
@ -416,6 +504,8 @@ struct mio_t
} xbuf; /* buffer to support sprintf */
} sprintf;
mio_stopreq_t stopreq; /* stop request to abort mio_loop() */
struct
{
mio_dev_t* head;
@ -450,7 +540,11 @@ struct mio_t
mio_cwq_t* cwqfl[MIO_CWQFL_SIZE]; /* list of free cwq objects */
/* platform specific fields below */
mio_mux_t* mux;
struct
{
mio_sys_mux_t* mux;
mio_sys_log_t* log;
} sys;
};
/* ========================================================================= */
@ -461,25 +555,38 @@ extern "C" {
MIO_EXPORT mio_t* mio_open (
mio_mmgr_t* mmgr,
mio_oow_t xtnsize,
mio_oow_t tmrcapa, /**< initial timer capacity */
mio_errnum_t* errnum
mio_oow_t xtnsize,
mio_cmgr_t* cmgr,
mio_oow_t tmrcapa, /**< initial timer capacity */
mio_errinf_t* errinf
);
MIO_EXPORT void mio_close (
mio_t* mio
mio_t* mio
);
MIO_EXPORT int mio_init (
mio_t* mio,
mio_mmgr_t* mmgr,
mio_oow_t tmrcapa
mio_t* mio,
mio_mmgr_t* mmgr,
mio_cmgr_t* cmgr,
mio_oow_t tmrcapa
);
MIO_EXPORT void mio_fini (
mio_t* mio
mio_t* mio
);
MIO_EXPORT int mio_getoption (
mio_t* mio,
mio_option_t id,
void* value
);
MIO_EXPORT int mio_setoption (
mio_t* mio,
mio_option_t id,
const void* value
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_mmgr_t* mio_getmmgr (mio_t* mio) { return mio->mmgr; }
@ -572,10 +679,10 @@ MIO_EXPORT void mio_stop (
);
MIO_EXPORT mio_dev_t* mio_makedev (
mio_t* mio,
mio_oow_t dev_size,
mio_dev_mth_t* dev_mth,
mio_dev_evcb_t* dev_evcb,
mio_t* mio,
mio_oow_t dev_size,
mio_dev_mth_t* dev_mth,
mio_dev_evcb_t* dev_evcb,
void* make_ctx
);
@ -585,7 +692,7 @@ MIO_EXPORT void mio_killdev (
);
MIO_EXPORT int mio_dev_ioctl (
mio_dev_t* dev,
mio_dev_t* dev,
int cmd,
void* arg
);
@ -594,7 +701,7 @@ MIO_EXPORT int mio_dev_watch (
mio_dev_t* dev,
mio_dev_watch_cmd_t cmd,
/** 0 or bitwise-ORed of #MIO_DEV_EVENT_IN and #MIO_DEV_EVENT_OUT */
int events
int events
);
MIO_EXPORT int mio_dev_read (
@ -619,19 +726,19 @@ MIO_EXPORT int mio_dev_timedread (
*/
MIO_EXPORT int mio_dev_write (
mio_dev_t* dev,
const void* data,
const void* data,
mio_iolen_t len,
void* wrctx,
void* wrctx,
const mio_devaddr_t* dstaddr
);
MIO_EXPORT int mio_dev_timedwrite (
mio_dev_t* dev,
const void* data,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx,
void* wrctx,
const mio_devaddr_t* dstaddr
);
@ -639,45 +746,9 @@ MIO_EXPORT void mio_dev_halt (
mio_dev_t* dev
);
/* ========================================================================= */
#define mio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
#define mio_cleartime(x) mio_inittime(x,0,0)
#define mio_cmptime(x,y) \
(((x)->sec == (y)->sec)? ((x)->nsec - (y)->nsec): \
((x)->sec - (y)->sec))
/* if time has been normalized properly, nsec must be equal to or
* greater than 0. */
#define mio_isnegtime(x) ((x)->sec < 0)
#define mio_ispostime(x) ((x)->sec > 0 || ((x)->sec == 0 && (x)->nsec > 0))
#define mio_iszerotime(x) ((x)->sec == 0 && (x)->nsec == 0)
/**
* The mio_gettime() function gets the current time.
*/
MIO_EXPORT void mio_gettime (
mio_ntime_t* nt
);
/**
* The mio_addtime() function adds x and y and stores the result in z
*/
MIO_EXPORT void mio_addtime (
const mio_ntime_t* x,
const mio_ntime_t* y,
mio_ntime_t* z
);
/**
* The mio_subtime() function subtract y from x and stores the result in z.
*/
MIO_EXPORT void mio_subtime (
const mio_ntime_t* x,
const mio_ntime_t* y,
mio_ntime_t* z
);
/* =========================================================================
* TIMER MANAGEMENT
* ========================================================================= */
/**
* The mio_instmrjob() function schedules a new event.
@ -897,6 +968,14 @@ MIO_EXPORT mio_bch_t* mio_dupbchars (
mio_oow_t bcslen
);
/* =========================================================================
* MISCELLANEOUS HELPER FUNCTIONS
* ========================================================================= */
MIO_EXPORT const mio_ooch_t* mio_errnum_to_errstr (
mio_errnum_t errnum
);
#ifdef __cplusplus
}

View File

@ -1,3 +1,29 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* this file is included by sck-addr.c */
static int str_to_ipv4 (const char_t* str, mio_oow_t len, struct in_addr* inaddr)

View File

@ -24,6 +24,8 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
#if defined(_WIN32)
# include <windows.h>
# include <errno.h>

View File

@ -74,6 +74,26 @@ static mio_errnum_t errno_to_errnum (int errcode)
case EIO: return MIO_EIOERR;
#endif
#if defined(EMFILE)
case EMFILE:
return MIO_EMFILE;
#endif
#if defined(ENFILE)
case ENFILE:
return MIO_ENFILE;
#endif
#if defined(ECONNREFUSED)
case ECONNREFUSED:
return MIO_ECONRF;
#endif
#if defined(ECONNRESETD)
case ECONNRESET:
return MIO_ECONRS;
#endif
default: return MIO_ESYSERR;
}
}

View File

@ -26,6 +26,84 @@
#include "mio-prv.h"
#if defined(_WIN32)
# include <windows.h>
# include <time.h>
# include <errno.h>
# include <io.h>
# include <fcntl.h>
#elif defined(__OS2__)
# define INCL_DOSDATETIME
# include <os2.h>
# include <time.h>
# include <errno.h>
# include <io.h>
# include <fcntl.h>
#elif defined(__DOS__)
# include <dos.h>
# include <time.h>
# include <errno.h>
# include <io.h>
# include <fcntl.h>
#elif defined(macintosh)
# include <Types.h>
# include <OSUtils.h>
# include <Timer.h>
# include <MacErrors.h>
/* TODO: a lot to do */
#elif defined(vms) || defined(__vms)
# define __NEW_STARLET 1
# include <starlet.h> /* (SYS$...) */
# include <ssdef.h> /* (SS$...) */
# include <lib$routines.h> /* (lib$...) */
/* TODO: a lot to do */
#else
# include <sys/types.h>
# include <unistd.h>
# include <fcntl.h>
# include <errno.h>
# if defined(HAVE_TIME_H)
# include <time.h>
# endif
# if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
# endif
#endif
struct mio_sys_log_t
{
struct
{
int fd;
int fd_flag; /* bitwise OR'ed fo logfd_flag_t bits */
struct
{
mio_bch_t buf[4096];
mio_oow_t len;
} out;
} log;
};
typedef mio_sys_log_t xtn_t;
#define GET_XTN(mio) (&(mio)->sys.log)
enum logfd_flag_t
{
LOGFD_TTY = (1 << 0),
LOGFD_OPENED_HERE = (1 << 1)
};
static int write_all (int fd, const mio_bch_t* ptr, mio_oow_t len)
{
while (len > 0)
@ -259,3 +337,52 @@ void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mi
flush_log (mio, logfd);
}
static MIO_INLINE void reset_log_to_default (xtn_t* xtn)
{
#if defined(ENABLE_LOG_INITIALLY)
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
#else
xtn->log.fd = -1;
xtn->log.fd_flag = 0;
#endif
}
void mio_sys_initlog (mio_t* mio)
{
xtn_t* xtn = GET_XTN(mio);
mio_bitmask_t logmask;
mio_oow_t pathlen;
/* TODO: */
#define LOG_FILE "/dev/stderr"
xtn->log.fd = open(LOG_FILE, O_CREAT | O_WRONLY | O_APPEND , 0644);
if (xtn->log.fd == -1)
{
/*mio_seterrbfmtwithsyserr (mio, 0, errno, "cannot open log file %hs", LOG_FILE);*/
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
}
else
{
xtn->log.fd_flag |= LOGFD_OPENED_HERE;
}
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
logmask = MIO_LOG_ALL_TYPES | MIO_LOG_ALL_LEVELS;
mio_setoption (mio, MIO_LOG_MASK, &logmask);
}
void mio_sys_finilog (mio_t* mio)
{
xtn_t* xtn = GET_XTN(mio);
if ((xtn->log.fd_flag & LOGFD_OPENED_HERE) && xtn->log.fd >= 0) close (xtn->log.fd);
reset_log_to_default (xtn);
}

377
mio/lib/sys-mux.c Normal file
View File

@ -0,0 +1,377 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
#if defined(HAVE_SYS_EPOLL_H)
# include <sys/epoll.h>
# define USE_EPOLL
#elif defined(HAVE_SYS_POLL_H)
# include <sys/poll.h>
# define USE_POLL
#else
# error NO SUPPORTED MULTIPLEXER
#endif
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
/* ========================================================================= */
#if defined(USE_POLL)
#define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t)
struct mio_sys_mux_t
{
struct
{
mio_oow_t* ptr;
mio_oow_t size;
mio_oow_t capa;
} map; /* handle to index */
struct
{
struct pollfd* pfd;
mio_dev_t** dptr;
mio_oow_t size;
mio_oow_t capa;
} pd; /* poll data */
};
int mio_sys_initmux (mio_t* mio)
{
mio_sys_mux_t* mux;
mux = (mio_sys_mux_t*)mio_callocmem(mio, MIO_SIZEOF(*mux));
if (!mux) return -1;
mio->sys.mux = mux;
return 0;
}
void mio_sys_finimux (mio_t* mio)
{
if (mio->sys.mux)
{
mio_freemem (mio, mio->sys.mux);
mio->sys.mux = MIO_NULL;
}
}
int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_capa)
{
mio_t* mio;
mio_sys_mux_t* mux;
mio_oow_t idx;
mio = dev->mio;
mux = (mio_sys_mux_t*)mio->sys.mux;
if (hnd >= mux->map.capa)
{
mio_oow_t new_capa;
mio_oow_t* tmp;
if (cmd != MIO_SYS_MUX_CMD_INSERT)
{
mio->errnum = MIO_ENOENT;
return -1;
}
new_capa = MIO_ALIGN_POW2((hnd + 1), 256);
tmp = MIO_MMGR_REALLOC(mio->mmgr, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp));
if (!tmp)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
for (idx = mux->map.capa; idx < new_capa; idx++)
tmp[idx] = MUX_INDEX_INVALID;
mux->map.ptr = tmp;
mux->map.capa = new_capa;
}
idx = mux->map.ptr[hnd];
if (idx != MUX_INDEX_INVALID)
{
if (cmd == MIO_SYS_MUX_CMD_INSERT)
{
mio->errnum = MIO_EEXIST;
return -1;
}
}
else
{
if (cmd != MIO_SYS_MUX_CMD_INSERT)
{
mio->errnum = MIO_ENOENT;
return -1;
}
}
switch (cmd)
{
case MIO_SYS_MUX_CMD_INSERT:
if (mux->pd.size >= mux->pd.capa)
{
mio_oow_t new_capa;
struct pollfd* tmp1;
mio_dev_t** tmp2;
new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256);
tmp1 = MIO_MMGR_REALLOC(mio->mmgr, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1));
if (!tmp1)
{
mio->errnum = MIO_ESYSMEM;
return -1;
}
tmp2 = MIO_MMGR_REALLOC (mio->mmgr, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2));
if (!tmp2)
{
MIO_MMGR_FREE (mio->mmgr, tmp1);
mio->errnum = MIO_ESYSMEM;
return -1;
}
mux->pd.pfd = tmp1;
mux->pd.dptr = tmp2;
mux->pd.capa = new_capa;
}
idx = mux->pd.size++;
mux->pd.pfd[idx].fd = hnd;
mux->pd.pfd[idx].events = 0;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN;
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT;
mux->pd.pfd[idx].revents = 0;
mux->pd.dptr[idx] = dev;
mux->map.ptr[hnd] = idx;
return 0;
case MIO_SYS_MUX_CMD_UPDATE:
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev);
mux->pd.pfd[idx].events = 0;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN;
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT;
return 0;
case MIO_SYS_MUX_CMD_DELETE:
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev);
mux->map.ptr[hnd] = MUX_INDEX_INVALID;
/* TODO: speed up deletion. allow a hole in the array.
* delay array compaction if there is a hole.
* set fd for the hole to -1 such that poll()
* ignores it. compact the array if another deletion
* is requested when there is an existing hole. */
idx++;
while (idx < mux->pd.size)
{
int fd;
mux->pd.pfd[idx - 1] = mux->pd.pfd[idx];
mux->pd.dptr[idx - 1] = mux->pd.dptr[idx];
fd = mux->pd.pfd[idx].fd;
mux->map.ptr[fd] = idx - 1;
idx++;
}
mux->pd.size--;
return 0;
default:
mio->errnum = MIO_EINVAL;
return -1;
}
}
#elif defined(USE_EPOLL)
struct mio_sys_mux_t
{
int hnd;
struct epoll_event revs[100]; /* TODO: is it a good size? */
};
int mio_sys_initmux (mio_t* mio)
{
mio_sys_mux_t* mux;
mux = (mio_sys_mux_t*)mio_callocmem(mio, MIO_SIZEOF(*mux));
if (!mux) return -1;
mux->hnd = epoll_create (1000);
if (mux->hnd == -1)
{
mio_seterrwithsyserr (mio, 0, errno);
mio_freemem (mio, mux);
return -1;
}
mio->sys.mux = mux;
return 0;
}
void mio_sys_finimux (mio_t* mio)
{
if (mio->sys.mux)
{
close (mio->sys.mux->hnd);
mio_Freemem (mio, mio->sys.mux);
mio->sys.mux = MIO_NULL;
}
}
int mio_sys_ctrlmux (mio_t* mio, int cmd, mio_dev_t* dev, int dev_capa)
{
static int epoll_cmd[] = { EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL };
struct epoll_event ev;
MIO_ASSERT (mio, mio == dev->mio);
ev.data.ptr = dev;
ev.events = EPOLLHUP | EPOLLERR /*| EPOLLET*/;
if (dev_capa & MIO_DEV_CAPA_IN_WATCHED)
{
ev.events |= EPOLLIN;
#if defined(EPOLLRDHUP)
ev.events |= EPOLLRDHUP;
#endif
if (dev_capa & MIO_DEV_CAPA_PRI_WATCHED) ev.events |= EPOLLPRI;
}
if (dev_capa & MIO_DEV_CAPA_OUT_WATCHED) ev.events |= EPOLLOUT;
if (epoll_ctl(mio->sys.mux->hnd, epoll_cmd[cmd], dev->dev_mth->getsyshnd(dev), &ev) == -1)
{
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
return 0;
}
#endif
static void mio_sys_waitmux (mio_t* mio)
{
#if defined(_WIN32)
/*
if (GetQueuedCompletionStatusEx (mio->iocp, mio->ovls, MIO_COUNTOF(mio->ovls), &nentries, timeout, FALSE) == FALSE)
{
// TODO: set errnum
return -1;
}
for (i = 0; i < nentries; i++)
{
}
*/
#elif defined(USE_POLL)
mux = (mio_sys_mux_t*)mio->sys.mux;
nentries = poll(mux->pd.pfd, mux->pd.size, MIO_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec));
if (nentries == -1)
{
if (errno == EINTR) return 0;
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
for (i = 0; i < mux->pd.size; i++)
{
if (mux->pd.pfd[i].fd >= 0 && mux->pd.pfd[i].revents)
{
int events = 0;
mio_dev_t* dev;
dev = mux->pd.dptr[i];
MIO_ASSERT (mio, !(mux->pd.pfd[i].revents & POLLNVAL));
if (mux->pd.pfd[i].revents & POLLIN) events |= MIO_DEV_EVENT_IN;
if (mux->pd.pfd[i].revents & POLLOUT) events |= MIO_DEV_EVENT_OUT;
if (mux->pd.pfd[i].revents & POLLPRI) events |= MIO_DEV_EVENT_PRI;
if (mux->pd.pfd[i].revents & POLLERR) events |= MIO_DEV_EVENT_ERR;
if (mux->pd.pfd[i].revents & POLLHUP) events |= MIO_DEV_EVENT_HUP;
handle_event (dev, events, 0);
}
}
#elif defined(USE_EPOLL)
mux = (mio_sys_mux_t*)mio->sys.mux;
nentries = epoll_wait(mux->hnd, mux->revs, MIO_COUNTOF(mux->revs), MIO_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec));
if (nentries == -1)
{
if (errno == EINTR) return 0; /* it's actually ok */
/* other errors are critical - EBADF, EFAULT, EINVAL */
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
/* TODO: merge events??? for the same descriptor */
for (i = 0; i < nentries; i++)
{
int events = 0, rdhup = 0;
mio_dev_t* dev;
dev = mux->revs[i].data.ptr;
if (mux->revs[i].events & EPOLLIN) events |= MIO_DEV_EVENT_IN;
if (mux->revs[i].events & EPOLLOUT) events |= MIO_DEV_EVENT_OUT;
if (mux->revs[i].events & EPOLLPRI) events |= MIO_DEV_EVENT_PRI;
if (mux->revs[i].events & EPOLLERR) events |= MIO_DEV_EVENT_ERR;
if (mux->revs[i].events & EPOLLHUP) events |= MIO_DEV_EVENT_HUP;
#if defined(EPOLLRDHUP)
else if (mux->revs[i].events & EPOLLRDHUP) rdhup = 1;
#endif
handle_event (dev, events, rdhup);
}
#else
# error NO SUPPORTED MULTIPLEXER
#endif
}

View File

@ -47,13 +47,23 @@
# include <errno.h>
#endif
#define MIO_EPOCH_YEAR (1970)
#define MIO_EPOCH_MON (1)
#define MIO_EPOCH_DAY (1)
#define MIO_EPOCH_WDAY (4)
/* windows specific epoch time */
#define MIO_EPOCH_YEAR_WIN (1601)
#define MIO_EPOCH_MON_WIN (1)
#define MIO_EPOCH_DAY_WIN (1)
#if defined(_WIN32)
#define EPOCH_DIFF_YEARS (MIO_EPOCH_YEAR-MIO_EPOCH_YEAR_WIN)
#define EPOCH_DIFF_DAYS ((mio_intptr_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
#define EPOCH_DIFF_SECS ((mio_intptr_t)EPOCH_DIFF_DAYS*24*60*60)
#endif
void mio_gettime (mio_ntime_t* t)
void mio_sys_gettime (mio_ntime_t* t)
{
#if defined(_WIN32)
SYSTEMTIME st;
@ -97,7 +107,7 @@ void mio_gettime (mio_ntime_t* t)
/*bt.msec = dt.hundredths * 10;*/
bt.isdst = -1; /* determine dst for me */
if (mio_timelocal (&bt, t) <= -1)
if (mio_timelocal(&bt, t) <= -1)
{
t->sec = time (MIO_NULL);
t->nsec = 0;
@ -126,7 +136,7 @@ void mio_gettime (mio_ntime_t* t)
/*bt.msec = dt.hsecond * 10; */
bt.isdst = -1; /* determine dst for me */
if (mio_timelocal (&bt, t) <= -1)
if (mio_timelocal(&bt, t) <= -1)
{
t->sec = time (MIO_NULL);
t->nsec = 0;
@ -146,7 +156,7 @@ void mio_gettime (mio_ntime_t* t)
#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts) == -1 && errno == EINVAL)
if (clock_gettime(CLOCK_REALTIME, &ts) == -1 && errno == EINVAL)
{
#if defined(HAVE_GETTIMEOFDAY)
struct timeval tv;
@ -173,33 +183,3 @@ void mio_gettime (mio_ntime_t* t)
t->nsec = 0;
#endif
}
void mio_addtime (const mio_ntime_t* x, const mio_ntime_t* y, mio_ntime_t* z)
{
MIO_ASSERT (x->nsec >= 0 && x->nsec < MIO_NSECS_PER_SEC);
MIO_ASSERT (y->nsec >= 0 && y->nsec < MIO_NSECS_PER_SEC);
z->sec = x->sec + y->sec;
z->nsec = x->nsec + y->nsec;
if (z->nsec >= MIO_NSECS_PER_SEC)
{
z->sec = z->sec + 1;
z->nsec = z->nsec - MIO_NSECS_PER_SEC;
}
}
void mio_subtime (const mio_ntime_t* x, const mio_ntime_t* y, mio_ntime_t* z)
{
MIO_ASSERT (x->nsec >= 0 && x->nsec < MIO_NSECS_PER_SEC);
MIO_ASSERT (y->nsec >= 0 && y->nsec < MIO_NSECS_PER_SEC);
z->sec = x->sec - y->sec;
z->nsec = x->nsec - y->nsec;
if (z->nsec < 0)
{
z->sec = z->sec - 1;
z->nsec = z->nsec + MIO_NSECS_PER_SEC;
}
}

View File

@ -31,7 +31,7 @@
#define HEAP_LEFT(x) ((x) * 2 + 1)
#define HEAP_RIGHT(x) ((x) * 2 + 2)
#define YOUNGER_THAN(x,y) (mio_cmptime(&(x)->when, &(y)->when) < 0)
#define YOUNGER_THAN(x,y) (MIO_CMP_NTIME(&(x)->when, &(y)->when) < 0)
void mio_cleartmrjobs (mio_t* mio)
{
@ -114,7 +114,7 @@ void mio_deltmrjob (mio_t* mio, mio_tmridx_t index)
{
mio_tmrjob_t item;
MIO_ASSERT (index < mio->tmr.size);
MIO_ASSERT (mio, index < mio->tmr.size);
item = mio->tmr.jobs[index];
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = MIO_TMRIDX_INVALID;
@ -137,7 +137,7 @@ mio_tmridx_t mio_instmrjob (mio_t* mio, const mio_tmrjob_t* job)
mio_tmrjob_t* tmp;
mio_oow_t new_capa;
MIO_ASSERT (mio->tmr.capa >= 1);
MIO_ASSERT (mio, mio->tmr.capa >= 1);
new_capa = mio->tmr.capa * 2;
tmp = (mio_tmrjob_t*)MIO_MMGR_REALLOC (mio->mmgr, mio->tmr.jobs, new_capa * MIO_SIZEOF(*tmp));
if (tmp == MIO_NULL)
@ -173,11 +173,11 @@ void mio_firetmrjobs (mio_t* mio, const mio_ntime_t* tm, mio_oow_t* firecnt)
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else mio_gettime (&now);
else mio_sys_gettime (&now);
while (mio->tmr.size > 0)
{
if (mio_cmptime(&mio->tmr.jobs[0].when, &now) > 0) break;
if (MIO_CMP_NTIME(&mio->tmr.jobs[0].when, &now) > 0) break;
tmrjob = mio->tmr.jobs[0]; /* copy the scheduled job */
mio_deltmrjob (mio, 0); /* deschedule the job */
@ -202,10 +202,10 @@ int mio_gettmrtmout (mio_t* mio, const mio_ntime_t* tm, mio_ntime_t* tmout)
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else mio_gettime (&now);
else mio_sys_gettime (&now);
mio_subtime (&mio->tmr.jobs[0].when, &now, tmout);
if (tmout->sec < 0) mio_cleartime (tmout);
MIO_SUB_NTIME (tmout, &mio->tmr.jobs[0].when, &now);
if (tmout->sec < 0) MIO_CLEAR_NTIME (tmout);
return 0;
}