From 446809d7f45f2ec3080ec0aa7a81df3cd6e1490c Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 27 Jan 2019 02:09:22 +0000 Subject: [PATCH] unfinished refactoring --- mio/configure | 12 + mio/configure.ac | 1 + mio/lib/Makefile | 2 - mio/lib/Makefile.am | 9 +- mio/lib/Makefile.in | 67 ++-- mio/lib/err.c | 1 + mio/lib/{logfmt.c => fmtout.c} | 86 ++--- mio/lib/{logfmtv.h => fmtoutv.h} | 10 +- mio/lib/main.c | 20 +- mio/lib/mio-cfg.h.in | 9 + mio/lib/mio-cmn.h | 7 + mio/lib/mio-pro.c | 16 +- mio/lib/mio-prv.h | 76 +++-- mio/lib/mio-sck.c | 92 +++--- mio/lib/mio.c | 540 ++++++++----------------------- mio/lib/mio.h | 201 ++++++++---- mio/lib/sck-addr.h | 26 ++ mio/lib/sys-ass.c | 2 + mio/lib/sys-err.c | 20 ++ mio/lib/sys-log.c | 127 ++++++++ mio/lib/sys-mux.c | 377 +++++++++++++++++++++ mio/lib/{mio-tim.c => sys-tim.c} | 48 +-- mio/lib/{mio-tmr.c => tmr.c} | 16 +- 23 files changed, 1070 insertions(+), 695 deletions(-) delete mode 100644 mio/lib/Makefile rename mio/lib/{logfmt.c => fmtout.c} (92%) rename mio/lib/{logfmtv.h => fmtoutv.h} (98%) create mode 100644 mio/lib/sys-mux.c rename mio/lib/{mio-tim.c => sys-tim.c} (83%) rename mio/lib/{mio-tmr.c => tmr.c} (94%) diff --git a/mio/configure b/mio/configure index 0f780d6..e18106a 100755 --- a/mio/configure +++ b/mio/configure @@ -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" diff --git a/mio/configure.ac b/mio/configure.ac index c083e5d..f9f117b 100644 --- a/mio/configure.ac +++ b/mio/configure.ac @@ -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" diff --git a/mio/lib/Makefile b/mio/lib/Makefile deleted file mode 100644 index 093220c..0000000 --- a/mio/lib/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - cc -g -I. -Wall -o mio main.c mio.c mio-tcp.c mio-udp.c mio-sck.c diff --git a/mio/lib/Makefile.am b/mio/lib/Makefile.am index 5d5aa4f..2a6cf08 100644 --- a/mio/lib/Makefile.am +++ b/mio/lib/Makefile.am @@ -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) diff --git a/mio/lib/Makefile.in b/mio/lib/Makefile.in index 9087fbd..41988ee 100644 --- a/mio/lib/Makefile.in +++ b/mio/lib/Makefile.in @@ -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 diff --git a/mio/lib/err.c b/mio/lib/err.c index 9207add..27285a0 100644 --- a/mio/lib/err.c +++ b/mio/lib/err.c @@ -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'}; diff --git a/mio/lib/logfmt.c b/mio/lib/fmtout.c similarity index 92% rename from mio/lib/logfmt.c rename to mio/lib/fmtout.c index f30e30b..4775209 100644 --- a/mio/lib/logfmt.c +++ b/mio/lib/fmtout.c @@ -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; diff --git a/mio/lib/logfmtv.h b/mio/lib/fmtoutv.h similarity index 98% rename from mio/lib/logfmtv.h rename to mio/lib/fmtoutv.h index c432f0b..53b2788 100644 --- a/mio/lib/logfmtv.h +++ b/mio/lib/fmtoutv.h @@ -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': diff --git a/mio/lib/main.c b/mio/lib/main.c index 11a5ec0..77c43ae 100644 --- a/mio/lib/main.c +++ b/mio/lib/main.c @@ -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) { diff --git a/mio/lib/mio-cfg.h.in b/mio/lib/mio-cfg.h.in index dbd15b9..e704750 100644 --- a/mio/lib/mio-cfg.h.in +++ b/mio/lib/mio-cfg.h.in @@ -250,6 +250,9 @@ /* Define to 1 if you have the 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 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 diff --git a/mio/lib/mio-cmn.h b/mio/lib/mio-cmn.h index 9babbfa..539be0a 100644 --- a/mio/lib/mio-cmn.h +++ b/mio/lib/mio-cmn.h @@ -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 * ========================================================================= */ diff --git a/mio/lib/mio-pro.c b/mio/lib/mio-pro.c index 333d25f..9b46a75 100644 --- a/mio/lib/mio-pro.c +++ b/mio/lib/mio-pro.c @@ -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; } } diff --git a/mio/lib/mio-prv.h b/mio/lib/mio-prv.h index 9d8b9c7..c9a4675 100644 --- a/mio/lib/mio-prv.h +++ b/mio/lib/mio-prv.h @@ -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 diff --git a/mio/lib/mio-sck.c b/mio/lib/mio-sck.c index 0959cd6..7d6ee62 100644 --- a/mio/lib/mio-sck.c +++ b/mio/lib/mio-sck.c @@ -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; } diff --git a/mio/lib/mio.c b/mio/lib/mio.c index 8e3d5ca..14e4a8c 100644 --- a/mio/lib/mio.c +++ b/mio/lib/mio.c @@ -26,20 +26,6 @@ #include "mio-prv.h" -#if defined(HAVE_SYS_EPOLL_H) -# include -# define USE_EPOLL -#elif defined(HAVE_SYS_POLL_H) -# include -# define USE_POLL -#else -# error NO SUPPORTED MULTIPLEXER -#endif - -#include -#include -#include - #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) diff --git a/mio/lib/mio.h b/mio/lib/mio.h index 37af758..93e551d 100644 --- a/mio/lib/mio.h +++ b/mio/lib/mio.h @@ -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 } diff --git a/mio/lib/sck-addr.h b/mio/lib/sck-addr.h index 59fb160..30e4c8f 100644 --- a/mio/lib/sck-addr.h +++ b/mio/lib/sck-addr.h @@ -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) diff --git a/mio/lib/sys-ass.c b/mio/lib/sys-ass.c index 94316fe..4aa5562 100644 --- a/mio/lib/sys-ass.c +++ b/mio/lib/sys-ass.c @@ -24,6 +24,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "mio-prv.h" + #if defined(_WIN32) # include # include diff --git a/mio/lib/sys-err.c b/mio/lib/sys-err.c index 600d8a9..4140dfd 100644 --- a/mio/lib/sys-err.c +++ b/mio/lib/sys-err.c @@ -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; } } diff --git a/mio/lib/sys-log.c b/mio/lib/sys-log.c index af0bd47..736b9e6 100644 --- a/mio/lib/sys-log.c +++ b/mio/lib/sys-log.c @@ -26,6 +26,84 @@ #include "mio-prv.h" +#if defined(_WIN32) +# include +# include +# include +# include +# include + +#elif defined(__OS2__) +# define INCL_DOSDATETIME +# include +# include +# include +# include +# include + +#elif defined(__DOS__) +# include +# include +# include +# include +# include + +#elif defined(macintosh) +# include +# include +# include +# include + + /* TODO: a lot to do */ + +#elif defined(vms) || defined(__vms) +# define __NEW_STARLET 1 +# include /* (SYS$...) */ +# include /* (SS$...) */ +# include /* (lib$...) */ + + /* TODO: a lot to do */ + +#else +# include +# include +# include +# include + +# if defined(HAVE_TIME_H) +# include +# endif +# if defined(HAVE_SYS_TIME_H) +# include +# 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); +} diff --git a/mio/lib/sys-mux.c b/mio/lib/sys-mux.c new file mode 100644 index 0000000..9e78524 --- /dev/null +++ b/mio/lib/sys-mux.c @@ -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 +# define USE_EPOLL +#elif defined(HAVE_SYS_POLL_H) +# include +# define USE_POLL +#else +# error NO SUPPORTED MULTIPLEXER +#endif + +#include +#include +#include + +/* ========================================================================= */ +#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 +} diff --git a/mio/lib/mio-tim.c b/mio/lib/sys-tim.c similarity index 83% rename from mio/lib/mio-tim.c rename to mio/lib/sys-tim.c index 46e4b83..9fcd69c 100644 --- a/mio/lib/mio-tim.c +++ b/mio/lib/sys-tim.c @@ -47,13 +47,23 @@ # include #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; - } -} diff --git a/mio/lib/mio-tmr.c b/mio/lib/tmr.c similarity index 94% rename from mio/lib/mio-tmr.c rename to mio/lib/tmr.c index b940594..33b9fe1 100644 --- a/mio/lib/mio-tmr.c +++ b/mio/lib/tmr.c @@ -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; }