refactoring system dependent code

This commit is contained in:
hyung-hwan 2019-01-29 16:57:16 +00:00
parent 792e4da4c2
commit 32abb82f01
10 changed files with 392 additions and 177 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

126
mio/lib/mio-sys.h Normal file
View File

@ -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 <sys/epoll.h>
# define USE_EPOLL
#elif defined(HAVE_SYS_POLL_H)
# include <sys/poll.h>
# define USE_POLL
#else
# error NO SUPPORTED MULTIPLEXER
#endif
/* -------------------------------------------------------------------------- */
#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

View File

@ -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);

View File

@ -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
}

View File

@ -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 <windows.h>
@ -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;
}

View File

@ -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 <sys/epoll.h>
# define USE_EPOLL
#elif defined(HAVE_SYS_POLL_H)
# include <sys/poll.h>
# define USE_POLL
#else
# error NO SUPPORTED MULTIPLEXER
#endif
#include "mio-sys.h"
#include <fcntl.h>
#include <unistd.h>
@ -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));

View File

@ -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

63
mio/lib/sys.c Normal file
View File

@ -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;
}