From 32abb82f01cc27f102f1f8f6ddef32ad50001a5d Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 29 Jan 2019 16:57:16 +0000 Subject: [PATCH] refactoring system dependent code --- mio/lib/Makefile.am | 2 + mio/lib/Makefile.in | 13 ++++- mio/lib/mio-prv.h | 35 +++-------- mio/lib/mio-sys.h | 126 ++++++++++++++++++++++++++++++++++++++++ mio/lib/mio.c | 43 +++++++------- mio/lib/mio.h | 50 ++++++++-------- mio/lib/sys-log.c | 31 ++-------- mio/lib/sys-mux.c | 69 ++++------------------ mio/lib/sys-tim.c | 137 +++++++++++++++++++++++++++++++++++++------- mio/lib/sys.c | 63 ++++++++++++++++++++ 10 files changed, 392 insertions(+), 177 deletions(-) create mode 100644 mio/lib/mio-sys.h create mode 100644 mio/lib/sys.c diff --git a/mio/lib/Makefile.am b/mio/lib/Makefile.am index 2a6cf08..c6efc8f 100644 --- a/mio/lib/Makefile.am +++ b/mio/lib/Makefile.am @@ -33,11 +33,13 @@ libmio_la_SOURCES = \ fmtout.c \ fmtoutv.h \ mio-prv.h \ + mio-sys.h \ mio.c \ mio-pro.c \ mio-sck.c \ sck-addr.c \ sck-addr.h \ + sys.c \ sys-ass.c \ sys-err.c \ sys-log.c \ diff --git a/mio/lib/Makefile.in b/mio/lib/Makefile.in index 68eb2a3..b17aa12 100644 --- a/mio/lib/Makefile.in +++ b/mio/lib/Makefile.in @@ -142,7 +142,7 @@ 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-fmtout.lo \ libmio_la-mio.lo libmio_la-mio-pro.lo libmio_la-mio-sck.lo \ - libmio_la-sck-addr.lo libmio_la-sys-ass.lo \ + libmio_la-sck-addr.lo libmio_la-sys.lo libmio_la-sys-ass.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 @@ -365,6 +365,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -405,11 +406,13 @@ libmio_la_SOURCES = \ fmtout.c \ fmtoutv.h \ mio-prv.h \ + mio-sys.h \ mio.c \ mio-pro.c \ mio-sck.c \ sck-addr.c \ sck-addr.h \ + sys.c \ sys-ass.c \ sys-err.c \ sys-log.c \ @@ -584,6 +587,7 @@ distclean-compile: @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-sys.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@ @@ -655,6 +659,13 @@ libmio_la-sck-addr.lo: sck-addr.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-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c +libmio_la-sys.lo: sys.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.lo -MD -MP -MF $(DEPDIR)/libmio_la-sys.Tpo -c -o libmio_la-sys.lo `test -f 'sys.c' || echo '$(srcdir)/'`sys.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sys.Tpo $(DEPDIR)/libmio_la-sys.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys.c' object='libmio_la-sys.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.lo `test -f 'sys.c' || echo '$(srcdir)/'`sys.c + libmio_la-sys-ass.lo: sys-ass.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-ass.lo -MD -MP -MF $(DEPDIR)/libmio_la-sys-ass.Tpo -c -o libmio_la-sys-ass.lo `test -f 'sys-ass.c' || echo '$(srcdir)/'`sys-ass.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sys-ass.Tpo $(DEPDIR)/libmio_la-sys-ass.Plo diff --git a/mio/lib/mio-prv.h b/mio/lib/mio-prv.h index 65254e4..764df45 100644 --- a/mio/lib/mio-prv.h +++ b/mio/lib/mio-prv.h @@ -135,6 +135,15 @@ void mio_seterrufmtv ( /* ========================================================================== */ /* system intefaces */ /* ========================================================================== */ + +int mio_sys_init ( + mio_t* mio +); + +void mio_sys_fini ( + mio_t* mio +); + void mio_sys_assertfail ( mio_t* mio, const mio_bch_t* expr, @@ -150,16 +159,6 @@ mio_errnum_t mio_sys_syserrstrb ( mio_oow_t len ); - - -int mio_sys_initlog ( - mio_t* mio -); - -void mio_sys_finilog ( - mio_t* mio -); - void mio_sys_writelog ( mio_t* mio, mio_bitmask_t mask, @@ -167,15 +166,6 @@ 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, @@ -189,13 +179,6 @@ int mio_sys_waitmux ( mio_sys_mux_evtcb_t event_handler ); -/** - * 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-sys.h b/mio/lib/mio-sys.h new file mode 100644 index 0000000..248e4e6 --- /dev/null +++ b/mio/lib/mio-sys.h @@ -0,0 +1,126 @@ +/* + * $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. + */ + +#ifndef _MIO_SYS_H_ +#define _MIO_SYS_H_ + +#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 + +/* -------------------------------------------------------------------------- */ + +#if defined(USE_POLL) + +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 */ +}; + +#elif defined(USE_EPOLL) + +struct mio_sys_mux_t +{ + int hnd; + struct epoll_event revs[100]; /* TODO: is it a good size? */ +}; + +#endif + +typedef struct mio_sys_mux_t mio_sys_mux_t; + +/* -------------------------------------------------------------------------- */ + +struct mio_sys_log_t +{ + int fd; + int fd_flag; /* bitwise OR'ed of logfd_flag_t bits */ + + struct + { + mio_bch_t buf[4096]; + mio_oow_t len; + } out; +}; +typedef struct mio_sys_log_t mio_sys_log_t; + +/* -------------------------------------------------------------------------- */ +struct mio_sys_t +{ + mio_sys_log_t log; + mio_sys_mux_t mux; + /*mio_sys_time_t time;*/ +}; + +/* -------------------------------------------------------------------------- */ + +#if defined(__cplusplus) +extern "C" { +#endif + +int mio_sys_initlog ( + mio_t* mio +); + +void mio_sys_finilog ( + mio_t* mio +); + +int mio_sys_initmux ( + mio_t* mio +); + +void mio_sys_finimux ( + mio_t* mio +); + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/mio/lib/mio.c b/mio/lib/mio.c index 5621ca7..5c8667f 100644 --- a/mio/lib/mio.c +++ b/mio/lib/mio.c @@ -86,8 +86,7 @@ void mio_close (mio_t* mio) 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; + int sys_inited = 0; MIO_MEMSET (mio, 0, MIO_SIZEOF(*mio)); mio->mmgr = mmgr; @@ -105,12 +104,8 @@ int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_cmgr_t* cmgr, mio_oow_t tmrcapa) if (!mio->log.ptr) goto oops; /* inititalize the system-side logging */ - if (mio_sys_initlog (mio) <= -1) goto oops; - sys_log_inited = 1; - - /* intialize the multiplexer object */ - if (mio_sys_initmux(mio) <= -1) goto oops; - sys_mux_inited = 1; + if (mio_sys_init(mio) <= -1) goto oops; + sys_inited = 1; /* initialize the timer object */ if (tmrcapa <= 0) tmrcapa = 1; @@ -125,8 +120,7 @@ int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_cmgr_t* cmgr, mio_oow_t tmrcapa) 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 (sys_inited) mio_sys_fini (mio); if (mio->log.ptr) mio_freemem (mio, mio->log.ptr); mio->log.capa = 0; @@ -203,8 +197,7 @@ void mio_fini (mio_t* mio) mio_cleartmrjobs (mio); mio_freemem (mio, mio->tmr.jobs); - mio_sys_finimux (mio); /* close the multiplexer */ - mio_sys_finilog (mio); /* close the system logger */ + mio_sys_fini (mio); /* finalize the system dependent data */ mio_freemem (mio, mio->log.ptr); } @@ -276,7 +269,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int { MIO_ASSERT (mio, mio == dev->mio); - dev->dev_capa &= ~MIO_DEV_RENEW_REQUIRED; + dev->dev_capa &= ~MIO_DEV_CAPA_RENEW_REQUIRED; MIO_ASSERT (mio, mio == dev->mio); @@ -353,7 +346,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int /* it was a zero-length write request. * for a stream, it is to close the output. */ dev->dev_capa |= MIO_DEV_CAPA_OUT_CLOSED; - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; out_closed = 1; } @@ -396,7 +389,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int } else { - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; } } } @@ -452,7 +445,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int /* EOF received. for a stream device, a zero-length * read is interpreted as EOF. */ dev->dev_capa |= MIO_DEV_CAPA_IN_CLOSED; - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; /* call the on_read callback to report EOF */ if (dev->dev_evcb->on_read(dev, mio->bigbuf, len, &srcaddr) <= -1 || @@ -501,7 +494,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int * EPOLLIN or EPOLLOUT check because EPOLLERR or EPOLLHUP * can be set together with EPOLLIN or EPOLLOUT. */ dev->dev_capa |= MIO_DEV_CAPA_IN_CLOSED | MIO_DEV_CAPA_OUT_CLOSED; - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; } else if (dev && rdhup) { @@ -513,7 +506,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int else { dev->dev_capa |= MIO_DEV_CAPA_IN_CLOSED | MIO_DEV_CAPA_OUT_CLOSED; - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; } } @@ -526,7 +519,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int } skip_evcb: - if (dev && (dev->dev_capa & MIO_DEV_RENEW_REQUIRED) && mio_dev_watch(dev, MIO_DEV_WATCH_RENEW, 0) <= -1) + if (dev && (dev->dev_capa & MIO_DEV_CAPA_RENEW_REQUIRED) && mio_dev_watch(dev, MIO_DEV_WATCH_RENEW, 0) <= -1) { mio_dev_halt (dev); dev = MIO_NULL; @@ -660,6 +653,7 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth, /* set some internal capability bits according to the capabilities * removed by the device making callback for convenience sake. */ + dev->dev_capa &= MIO_DEV_CAPA_ALL_MASK; /* keep valid capability bits only. drop all internal-use bits */ if (!(dev->dev_capa & MIO_DEV_CAPA_IN)) dev->dev_capa |= MIO_DEV_CAPA_IN_CLOSED; if (!(dev->dev_capa & MIO_DEV_CAPA_OUT)) dev->dev_capa |= MIO_DEV_CAPA_OUT_CLOSED; @@ -906,7 +900,11 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events) switch (cmd) { case MIO_DEV_WATCH_START: - events = 0; /* MIO_DEV_EVENT_IN if you want input watching to be enabled upon device creation */ + /* request input watching when a device is started. + * if the device is set with MIO_DEV_CAPA_IN_DISABLED and/or + * is not set with MIO_DEV_CAPA_IN, input wathcing is excluded + * after this 'switch' block */ + events = MIO_DEV_EVENT_IN; mux_cmd = MIO_SYS_MUX_CMD_INSERT; break; @@ -1002,7 +1000,7 @@ static int __dev_read (mio_dev_t* dev, int enabled, const mio_ntime_t* tmout, vo if ((dev->dev_capa & MIO_DEV_CAPA_IN_WATCHED)) goto renew_watch_now; } - dev->dev_capa |= MIO_DEV_RENEW_REQUIRED; + dev->dev_capa |= MIO_DEV_CAPA_RENEW_REQUIRED; goto update_timer; renew_watch_now: @@ -1152,12 +1150,15 @@ static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const return 1; /* written immediately and called on_write callback */ enqueue_data: +#if 0 + /* TODO: DO WE REALLY NEED THIS CAPABILITY CHECK? If not, undefine MIO_DEV_CAPA_OUT_QUEUED */ if (!(dev->dev_capa & MIO_DEV_CAPA_OUT_QUEUED)) { /* writing queuing is not requested. so return failure */ mio_seterrbfmt (mio, MIO_ENOCAPA, "device incapable of queuing"); return -1; } +#endif /* queue the remaining data*/ q = (mio_wq_t*)mio_allocmem(mio, MIO_SIZEOF(*q) + (dstaddr? dstaddr->len: 0) + urem); diff --git a/mio/lib/mio.h b/mio/lib/mio.h index 5e853cb..fe63a69 100644 --- a/mio/lib/mio.h +++ b/mio/lib/mio.h @@ -338,25 +338,25 @@ enum mio_dev_capa_t MIO_DEV_CAPA_VIRTUAL = (1 << 0), MIO_DEV_CAPA_IN = (1 << 1), MIO_DEV_CAPA_OUT = (1 << 2), - /* #MIO_DEV_CAPA_PRI is meaningful only if #MIO_DEV_CAPA_IN is set */ - MIO_DEV_CAPA_PRI = (1 << 3), + MIO_DEV_CAPA_PRI = (1 << 3), /* meaningful only if #MIO_DEV_CAPA_IN is set */ MIO_DEV_CAPA_STREAM = (1 << 4), - MIO_DEV_CAPA_OUT_QUEUED = (1 << 5), + MIO_DEV_CAPA_IN_DISABLED = (1 << 5), + MIO_DEV_CAPA_OUT_QUEUED = (1 << 6), + MIO_DEV_CAPA_ALL_MASK = (MIO_DEV_CAPA_VIRTUAL | MIO_DEV_CAPA_IN | MIO_DEV_CAPA_OUT | MIO_DEV_CAPA_PRI | MIO_DEV_CAPA_STREAM | MIO_DEV_CAPA_IN_DISABLED | MIO_DEV_CAPA_OUT_QUEUED), - /* internal use only. never set this bit to the dev_capa field */ - MIO_DEV_CAPA_IN_DISABLED = (1 << 9), - MIO_DEV_CAPA_IN_CLOSED = (1 << 10), - MIO_DEV_CAPA_OUT_CLOSED = (1 << 11), - MIO_DEV_CAPA_IN_WATCHED = (1 << 12), - MIO_DEV_CAPA_OUT_WATCHED = (1 << 13), - MIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if MIO_DEV_CAPA_IN_WATCHED is set */ - - MIO_DEV_CAPA_ACTIVE = (1 << 15), - MIO_DEV_CAPA_HALTED = (1 << 16), - MIO_DEV_CAPA_ZOMBIE = (1 << 17), - - /* internal use only */ - MIO_DEV_RENEW_REQUIRED = (1 << 20) + /* ------------------------------------------------------------------- + * the followings bits are for internal use only. + * never set these bits to the dev_capa field. + * ------------------------------------------------------------------- */ + MIO_DEV_CAPA_IN_CLOSED = (1 << 10), + MIO_DEV_CAPA_OUT_CLOSED = (1 << 11), + MIO_DEV_CAPA_IN_WATCHED = (1 << 12), + MIO_DEV_CAPA_OUT_WATCHED = (1 << 13), + MIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if MIO_DEV_CAPA_IN_WATCHED is set */ + MIO_DEV_CAPA_ACTIVE = (1 << 15), + MIO_DEV_CAPA_HALTED = (1 << 16), + MIO_DEV_CAPA_ZOMBIE = (1 << 17), + MIO_DEV_CAPA_RENEW_REQUIRED = (1 << 18) }; typedef enum mio_dev_capa_t mio_dev_capa_t; @@ -459,7 +459,6 @@ enum mio_sys_mux_cmd_t }; typedef enum mio_sys_mux_cmd_t mio_sys_mux_cmd_t; - typedef void (*mio_sys_mux_evtcb_t) ( mio_t* mio, mio_dev_t* dev, @@ -467,8 +466,7 @@ typedef void (*mio_sys_mux_evtcb_t) ( int rdhup ); -typedef struct mio_sys_mux_t mio_sys_mux_t; -typedef struct mio_sys_log_t mio_sys_log_t; +typedef struct mio_sys_t mio_sys_t; struct mio_t { @@ -548,11 +546,7 @@ struct mio_t mio_cwq_t* cwqfl[MIO_CWQFL_SIZE]; /* list of free cwq objects */ /* platform specific fields below */ - struct - { - mio_sys_mux_t* mux; - mio_sys_log_t* log; - } sys; + mio_sys_t* sysdep; }; /* ========================================================================= */ @@ -1009,6 +1003,12 @@ MIO_EXPORT const mio_ooch_t* mio_errnum_to_errstr ( mio_errnum_t errnum ); +/** + * The mio_sys_gettime() function gets the current time. + */ +MIO_EXPORT void mio_sys_gettime ( + mio_ntime_t* now +); #ifdef __cplusplus } diff --git a/mio/lib/sys-log.c b/mio/lib/sys-log.c index f1f63c2..2032bb5 100644 --- a/mio/lib/sys-log.c +++ b/mio/lib/sys-log.c @@ -24,7 +24,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "mio-prv.h" +#include "mio-sys.h" #if defined(_WIN32) # include @@ -79,18 +79,6 @@ #endif -struct mio_sys_log_t -{ - int fd; - int fd_flag; /* bitwise OR'ed fo logfd_flag_t bits */ - - struct - { - mio_bch_t buf[4096]; - mio_oow_t len; - } out; -}; - enum logfd_flag_t { LOGFD_TTY = (1 << 0), @@ -133,7 +121,7 @@ static int write_all (int fd, const mio_bch_t* ptr, mio_oow_t len) static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len) { - mio_sys_log_t* log = mio->sys.log; + mio_sys_log_t* log = &mio->sysdep->log; while (len > 0) { @@ -184,7 +172,7 @@ static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len) static void flush_log (mio_t* mio, int fd) { - mio_sys_log_t* log = mio->sys.log; + mio_sys_log_t* log = &mio->sysdep->log; if (log->out.len > 0) { write_all (fd, log->out.buf, log->out.len); @@ -194,7 +182,7 @@ static void flush_log (mio_t* mio, int fd) void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mio_oow_t len) { - mio_sys_log_t* log = mio->sys.log; + mio_sys_log_t* log = &mio->sysdep->log; mio_bch_t buf[256]; mio_oow_t ucslen, bcslen, msgidx; int n, logfd; @@ -327,13 +315,10 @@ void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mi int mio_sys_initlog (mio_t* mio) { - mio_sys_log_t* log; + mio_sys_log_t* log = &mio->sysdep->log; mio_bitmask_t logmask; /*mio_oow_t pathlen;*/ - log = (mio_sys_log_t*)mio_callocmem(mio, MIO_SIZEOF(*log)); - if (!log) return -1; - /* TODO: */ #define LOG_FILE "/dev/stderr" log->fd = open(LOG_FILE, O_CREAT | O_WRONLY | O_APPEND , 0644); @@ -355,13 +340,12 @@ int mio_sys_initlog (mio_t* mio) logmask = MIO_LOG_ALL_TYPES | MIO_LOG_ALL_LEVELS; mio_setoption (mio, MIO_LOG_MASK, &logmask); - mio->sys.log = log; return 0; } void mio_sys_finilog (mio_t* mio) { - mio_sys_log_t* log = mio->sys.log; + mio_sys_log_t* log = &mio->sysdep->log; if ((log->fd_flag & LOGFD_OPENED_HERE) && log->fd >= 0) { @@ -369,7 +353,4 @@ void mio_sys_finilog (mio_t* mio) log->fd = -1; log->fd_flag = 0; } - - mio_freemem (mio, log); - mio->sys.log = MIO_NULL; } diff --git a/mio/lib/sys-mux.c b/mio/lib/sys-mux.c index 0dc89be..32279b1 100644 --- a/mio/lib/sys-mux.c +++ b/mio/lib/sys-mux.c @@ -24,17 +24,7 @@ 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 "mio-sys.h" #include #include @@ -42,79 +32,39 @@ /* ========================================================================= */ #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 */ -}; - -#elif defined(USE_EPOLL) - -struct mio_sys_mux_t -{ - int hnd; - struct epoll_event revs[100]; /* TODO: is it a good size? */ -}; - +# define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t) #endif 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_t* mux = &mio->sysdep->mux; #if defined(USE_EPOLL) mux->hnd = epoll_create(1000); /* TODO: choose proper initial size? */ if (mux->hnd == -1) { mio_seterrwithsyserr (mio, 0, errno); - mio_freemem (mio, mux); return -1; } #endif - mio->sys.mux = mux; return 0; } void mio_sys_finimux (mio_t* mio) { - if (mio->sys.mux) - { + mio_sys_mux_t* mux = &mio->sysdep->mux; #if defined(USE_EPOLL) - close (mio->sys.mux->hnd); + close (mux->hnd); #endif - 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) { #if defined(USE_POLL) - mio_t* mio = dev->mio; - mio_sys_mux_t* mux; + mio_sys_mux_t* mux = &mio->sysdep->mux; mio_oow_t idx; - mux = (mio_sys_mux_t*)mio->sys.mux; - if (dev->hnd >= mux->map.capa) { mio_oow_t new_capa; @@ -235,6 +185,7 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ return -1; } #elif defined(USE_EPOLL) + mio_sys_mux_t* mux = &mio->sysdep->mux; static int epoll_cmd[] = { EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL }; struct epoll_event ev; @@ -254,7 +205,7 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ 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) + if (epoll_ctl(mux->hnd, epoll_cmd[cmd], dev->dev_mth->getsyshnd(dev), &ev) == -1) { mio_seterrwithsyserr (mio, 0, errno); return -1; @@ -271,7 +222,7 @@ int mio_sys_waitmux (mio_t* mio, const mio_ntime_t* tmout, mio_sys_mux_evtcb_t e #if defined(USE_POLL) int nentries; - mux = (mio_sys_mux_t*)mio->sys.mux; + mux = (mio_sys_mux_t*)mio->sysdep->mux; nentries = poll(mux->pd.pfd, mux->pd.size, MIO_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec)); if (nentries == -1) @@ -303,7 +254,7 @@ int mio_sys_waitmux (mio_t* mio, const mio_ntime_t* tmout, mio_sys_mux_evtcb_t e #elif defined(USE_EPOLL) - mio_sys_mux_t* mux = mio->sys.mux; + mio_sys_mux_t* mux = &mio->sysdep->mux; int nentries, i; nentries = epoll_wait(mux->hnd, mux->revs, MIO_COUNTOF(mux->revs), MIO_SECNSEC_TO_MSEC(tmout->sec, tmout->nsec)); diff --git a/mio/lib/sys-tim.c b/mio/lib/sys-tim.c index 9fcd69c..9980030 100644 --- a/mio/lib/sys-tim.c +++ b/mio/lib/sys-tim.c @@ -63,7 +63,8 @@ #define EPOCH_DIFF_SECS ((mio_intptr_t)EPOCH_DIFF_DAYS*24*60*60) #endif -void mio_sys_gettime (mio_ntime_t* t) +#if 0 +void mio_sys_gettime (mio_ntime_t* now) { #if defined(_WIN32) SYSTEMTIME st; @@ -82,8 +83,8 @@ void mio_sys_gettime (mio_ntime_t* t) li.HighPart = ft.dwHighDateTime; /* li.QuadPart is in the 100-nanosecond intervals */ - t->sec = (li.QuadPart / (MIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS; - t->nsec = (li.QuadPart % (MIO_NSECS_PER_SEC / 100)) * 100; + now->sec = (li.QuadPart / (MIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS; + now->nsec = (li.QuadPart % (MIO_NSECS_PER_SEC / 100)) * 100; #elif defined(__OS2__) @@ -109,12 +110,12 @@ void mio_sys_gettime (mio_ntime_t* t) if (mio_timelocal(&bt, t) <= -1) { - t->sec = time (MIO_NULL); - t->nsec = 0; + now->sec = time (MIO_NULL); + now->nsec = 0; } else { - t->nsec = MIO_MSEC_TO_NSEC(dt.hundredths * 10); + now->nsec = MIO_MSEC_TO_NSEC(dt.hundredths * 10); } return 0; @@ -138,19 +139,19 @@ void mio_sys_gettime (mio_ntime_t* t) if (mio_timelocal(&bt, t) <= -1) { - t->sec = time (MIO_NULL); - t->nsec = 0; + now->sec = time (MIO_NULL); + now->nsec = 0; } else { - t->nsec = MIO_MSEC_TO_NSEC(dt.hsecond * 10); + now->nsec = MIO_MSEC_TO_NSEC(dt.hsecond * 10); } #elif defined(macintosh) unsigned long tv; GetDateTime (&tv); - t->sec = tv; + now->sec = tv; tv->nsec = 0; #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) @@ -161,25 +162,121 @@ void mio_sys_gettime (mio_ntime_t* t) #if defined(HAVE_GETTIMEOFDAY) struct timeval tv; gettimeofday (&tv, MIO_NULL); - t->sec = tv.tv_sec; - t->nsec = MIO_USEC_TO_NSEC(tv.tv_usec); + now->sec = tv.tv_sec; + now->nsec = MIO_USEC_TO_NSEC(tv.tv_usec); #else - t->sec = time (MIO_NULL); - t->nsec = 0; + now->sec = time (MIO_NULL); + now->nsec = 0; #endif } - t->sec = ts.tv_sec; - t->nsec = ts.tv_nsec; + now->sec = ts.tv_sec; + now->nsec = ts.tv_nsec; #elif defined(HAVE_GETTIMEOFDAY) struct timeval tv; gettimeofday (&tv, MIO_NULL); - t->sec = tv.tv_sec; - t->nsec = MIO_USEC_TO_NSEC(tv.tv_usec); + now->sec = tv.tv_sec; + now->nsec = MIO_USEC_TO_NSEC(tv.tv_usec); #else - t->sec = time(MIO_NULL); - t->nsec = 0; + now->sec = time(MIO_NULL); + now->nsec = 0; #endif } + +#else + +void mio_sys_gettime (mio_ntime_t* now) +{ +#if defined(_WIN32) + + #if defined(_WIN64) || (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)) + mio_uint64_t bigsec, bigmsec; + bigmsec = GetTickCount64(); + #else + xtn_t* xtn = GET_XTN(mio); + mio_uint64_t bigsec, bigmsec; + DWORD msec; + + msec = GetTickCount(); /* this can sustain for 49.7 days */ + if (msec < xtn->tc_last) + { + /* i assume the difference is never bigger than 49.7 days */ + /*diff = (MIO_TYPE_MAX(DWORD) - xtn->tc_last) + 1 + msec;*/ + xtn->tc_overflow++; + bigmsec = ((mio_uint64_t)MIO_TYPE_MAX(DWORD) * xtn->tc_overflow) + msec; + } + else bigmsec = msec; + xtn->tc_last = msec; + #endif + + bigsec = MIO_MSEC_TO_SEC(bigmsec); + bigmsec -= MIO_SEC_TO_MSEC(bigsec); + MIO_INIT_NTIME(now, bigsec, MIO_MSEC_TO_NSEC(bigmsec)); + +#elif defined(__OS2__) + xtn_t* xtn = GET_XTN(mio); + ULONG msec, elapsed; + mio_ntime_t et; + +/* TODO: use DosTmrQueryTime() and DosTmrQueryFreq()? */ + DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, &msec, MIO_SIZEOF(msec)); /* milliseconds */ + + elapsed = (msec < xtn->tc_last)? (MIO_TYPE_MAX(ULONG) - xtn->tc_last + msec + 1): (msec - xtn->tc_last); + xtn->tc_last = msec; + + et.sec = MIO_MSEC_TO_SEC(elapsed); + msec = elapsed - MIO_SEC_TO_MSEC(et.sec); + et.nsec = MIO_MSEC_TO_NSEC(msec); + + MIO_ADD_NTIME (&xtn->tc_last_ret , &xtn->tc_last_ret, &et); + *now = xtn->tc_last_ret; + +#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) + xtn_t* xtn = GET_XTN(mio); + clock_t c, elapsed; + mio_ntime_t et; + + c = clock(); + elapsed = (c < xtn->tc_last)? (MIO_TYPE_MAX(clock_t) - xtn->tc_last + c + 1): (c - xtn->tc_last); + xtn->tc_last = c; + + et.sec = elapsed / CLOCKS_PER_SEC; + #if (CLOCKS_PER_SEC == 100) + et.nsec = MIO_MSEC_TO_NSEC((elapsed % CLOCKS_PER_SEC) * 10); + #elif (CLOCKS_PER_SEC == 1000) + et.nsec = MIO_MSEC_TO_NSEC(elapsed % CLOCKS_PER_SEC); + #elif (CLOCKS_PER_SEC == 1000000L) + et.nsec = MIO_USEC_TO_NSEC(elapsed % CLOCKS_PER_SEC); + #elif (CLOCKS_PER_SEC == 1000000000L) + et.nsec = (elapsed % CLOCKS_PER_SEC); + #else + # error UNSUPPORTED CLOCKS_PER_SEC + #endif + + MIO_ADD_NTIME (&xtn->tc_last_ret , &xtn->tc_last_ret, &et); + *now = xtn->tc_last_ret; + +#elif defined(macintosh) + UnsignedWide tick; + mio_uint64_t tick64; + Microseconds (&tick); + tick64 = *(mio_uint64_t*)&tick; + MIO_INIT_NTIME (now, MIO_USEC_TO_SEC(tick64), MIO_USEC_TO_NSEC(tick64)); +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + MIO_INIT_NTIME(now, ts.tv_sec, ts.tv_nsec); +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) + struct timespec ts; + clock_gettime (CLOCK_REALTIME, &ts); + MIO_INIT_NTIME(now, ts.tv_sec, ts.tv_nsec); +#else + struct timeval tv; + gettimeofday (&tv, MIO_NULL); + MIO_INIT_NTIME(now, tv.tv_sec, MIO_USEC_TO_NSEC(tv.tv_usec)); +#endif +} + +#endif diff --git a/mio/lib/sys.c b/mio/lib/sys.c new file mode 100644 index 0000000..68c7067 --- /dev/null +++ b/mio/lib/sys.c @@ -0,0 +1,63 @@ +/* + * $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-sys.h" + +int mio_sys_init (mio_t* mio) +{ + int log_inited = 0; + int mux_inited = 0; + + mio->sysdep = (mio_sys_t*)mio_callocmem(mio, MIO_SIZEOF(*mio->sysdep)); + if (!mio->sysdep) return -1; + + if (mio_sys_initlog(mio) <= -1) goto oops; + log_inited = 1; + + if (mio_sys_initmux(mio) <= -1) goto oops; + mux_inited = 1; + + return 0; + +oops: + if (mux_inited) mio_sys_finimux (mio); + if (log_inited) mio_sys_finilog (mio); + if (mio->sysdep) + { + mio_freemem (mio, mio->sysdep); + mio->sysdep = MIO_NULL; + } + return -1; +} + +void mio_sys_fini (mio_t* mio) +{ + mio_sys_finimux (mio); + mio_sys_finilog (mio); + + mio_freemem (mio, mio->sysdep); + mio->sysdep = MIO_NULL; +}