added timer functions

This commit is contained in:
hyung-hwan 2018-03-15 08:35:38 +00:00
parent b56218ee25
commit 6f69e018c4
12 changed files with 511 additions and 56 deletions

View File

@ -353,7 +353,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -584,7 +583,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@ -610,7 +609,7 @@ dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@ -628,7 +627,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@ -638,7 +637,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac

14
configure vendored
View File

@ -779,7 +779,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -872,7 +871,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1125,15 +1123,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1271,7 +1260,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1424,7 +1413,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]

View File

@ -36,6 +36,7 @@ pkginclude_HEADERS = \
hcl-cfg.h \
hcl-cmn.h \
hcl-rbt.h \
hcl-tmr.h \
hcl-utl.h \
hcl.h
@ -63,6 +64,7 @@ libhcl_la_SOURCES = \
rbt.c \
read.c \
sym.c \
tmr.c \
utf8.c \
utl.c
libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)

View File

@ -158,7 +158,8 @@ am_libhcl_la_OBJECTS = libhcl_la-bigint.lo libhcl_la-comp.lo \
libhcl_la-hcl.lo libhcl_la-heap.lo libhcl_la-logfmt.lo \
libhcl_la-obj.lo libhcl_la-opt.lo libhcl_la-prim.lo \
libhcl_la-print.lo libhcl_la-rbt.lo libhcl_la-read.lo \
libhcl_la-sym.lo libhcl_la-utf8.lo libhcl_la-utl.lo
libhcl_la-sym.lo libhcl_la-tmr.lo libhcl_la-utf8.lo \
libhcl_la-utl.lo
libhcl_la_OBJECTS = $(am_libhcl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -399,7 +400,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -428,6 +428,7 @@ pkginclude_HEADERS = \
hcl-cfg.h \
hcl-cmn.h \
hcl-rbt.h \
hcl-tmr.h \
hcl-utl.h \
hcl.h
@ -455,6 +456,7 @@ libhcl_la_SOURCES = \
rbt.c \
read.c \
sym.c \
tmr.c \
utf8.c \
utl.c
@ -651,6 +653,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-rbt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-read.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-sym.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utf8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcls_la-hcl-s.Plo@am__quote@
@ -805,6 +808,13 @@ libhcl_la-sym.lo: sym.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) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-sym.lo `test -f 'sym.c' || echo '$(srcdir)/'`sym.c
libhcl_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) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-tmr.lo -MD -MP -MF $(DEPDIR)/libhcl_la-tmr.Tpo -c -o libhcl_la-tmr.lo `test -f 'tmr.c' || echo '$(srcdir)/'`tmr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-tmr.Tpo $(DEPDIR)/libhcl_la-tmr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tmr.c' object='libhcl_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) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-tmr.lo `test -f 'tmr.c' || echo '$(srcdir)/'`tmr.c
libhcl_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) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-utf8.lo -MD -MP -MF $(DEPDIR)/libhcl_la-utf8.Tpo -c -o libhcl_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-utf8.Tpo $(DEPDIR)/libhcl_la-utf8.Plo

View File

@ -947,7 +947,8 @@ typedef union sockaddr_t sockaddr_t;
#include "sa-utl.h"
/* ========================================================================= */
#define HCL_SERVER_PROTO_LOG_MASK (HCL_LOG_ERROR | HCL_LOG_APP)
#define SERVER_LOGMASK_INFO (HCL_LOG_INFO | HCL_LOG_APP)
#define SERVER_LOGMASK_ERROR (HCL_LOG_ERROR | HCL_LOG_APP)
hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_t* worker)
{
@ -1058,7 +1059,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
{
/* error occurred inside the worker thread shouldn't affect the error information
* in the server object. so here, i just log a message */
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "sendmsg failure on %d - %hs\n", proto->worker->sck, strerror(errno));
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "sendmsg failure on %d - %hs\n", proto->worker->sck, strerror(errno));
return -1;
}
@ -1257,7 +1258,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c)
tmp = (hcl_ooch_t*)HCL_MMGR_REALLOC(proto->worker->server->mmgr, proto->tok.ptr, capa * HCL_SIZEOF(*tmp));
if (!tmp)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "out of memory in allocating a token buffer\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "out of memory in allocating a token buffer\n");
return -1;
}
@ -1334,7 +1335,7 @@ static int get_token (hcl_server_proto_t* proto)
GET_CHAR_TO(proto, c);
if (!is_alphachar(c))
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "alphabetic character expected after a period\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "alphabetic character expected after a period\n");
return -1;
}
@ -1351,7 +1352,7 @@ static int get_token (hcl_server_proto_t* proto)
break;
default:
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "unrecognized character - [%jc]\n", c);
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unrecognized character - [%jc]\n", c);
return -1;
}
return 0;
@ -1370,7 +1371,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
case HCL_SERVER_PROTO_TOKEN_EOF:
if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "unexpected EOF without .END\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unexpected EOF without .END\n");
return -1;
}
@ -1380,21 +1381,21 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
case HCL_SERVER_PROTO_TOKEN_EXIT:
if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, ".EXIT allowed in the top level only\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".EXIT allowed in the top level only\n");
return -1;
}
if (get_token(proto) <= -1) return -1;
if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "no new line after .EXIT\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .EXIT\n");
return -1;
}
hcl_server_proto_start_reply (proto);
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .EXIT\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .EXIT\n");
return -1;
}
return 0;
@ -1402,14 +1403,14 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
case HCL_SERVER_PROTO_TOKEN_BEGIN:
if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, ".BEGIN not allowed to be nested\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".BEGIN not allowed to be nested\n");
return -1;
}
if (get_token(proto) <= -1) return -1;
if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "no new line after .BEGIN\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .BEGIN\n");
return -1;
}
@ -1423,14 +1424,14 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_BLOCK_LEVEL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, ".END without opening .BEGIN\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, ".END without opening .BEGIN\n");
return -1;
}
if (get_token(proto) <= -1) return -1;
if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "no new line after .BEGIN\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .BEGIN\n");
return -1;
}
@ -1438,7 +1439,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
obj = (hcl_getbclen(proto->hcl) > 0)? hcl_execute(proto->hcl): proto->hcl->_nil;
if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .END\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .END\n");
return -1;
}
@ -1455,20 +1456,20 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
obj = hcl_read(proto->hcl);
if (!obj)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot read .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl));
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot read .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl));
return -1;
}
if (get_token(proto) <= -1) return -1;
if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "no new line after .SCRIPT contest\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "no new line after .SCRIPT contest\n");
return -1;
}
if (hcl_compile(proto->hcl, obj) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot compile .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl));
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot compile .SCRIPT contents - %js\n", hcl_geterrmsg(proto->hcl));
return -1;
}
@ -1478,7 +1479,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
obj = hcl_execute(proto->hcl);
if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .SCRIPT\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .SCRIPT\n");
return -1;
}
}
@ -1495,7 +1496,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .SHOW-WORKERS\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .SHOW-WORKERS\n");
return -1;
}
@ -1510,13 +1511,13 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
{
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .KILL-WORKER\n");
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "cannot finalize reply for .KILL-WORKER\n");
return -1;
}
break;
default:
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "unknown token - %d - %.*js\n", (int)proto->tok.type, proto->tok.len, proto->tok.ptr);
hcl_logbfmt (proto->hcl, SERVER_LOGMASK_ERROR, "unknown token - %d - %.*js\n", (int)proto->tok.type, proto->tok.len, proto->tok.ptr);
return -1;
}
@ -1597,9 +1598,26 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck)
return worker;
}
static void close_worker_socket (hcl_server_worker_t* worker)
{
if (worker->sck >= 0)
{
if (worker->proto)
{
hcl_logbfmt (worker->proto->hcl, SERVER_LOGMASK_INFO, "closing worker socket %d\n", worker->sck);
}
else
{
hcl_server_logbfmt (worker->server, SERVER_LOGMASK_INFO, "closing worker socket %d\n", worker->sck);
}
close (worker->sck);
worker->sck = -1;
}
}
static void free_worker (hcl_server_worker_t* worker)
{
if (worker->sck >= 0) close (worker->sck);
close_worker_socket (worker);
HCL_MMGR_FREE (worker->server->mmgr, worker);
}
@ -1671,11 +1689,7 @@ static void* worker_main (void* ctx)
worker->proto = HCL_NULL;
pthread_mutex_lock (&server->worker_mutex);
/* close connection before free_client() is called */
close (worker->sck);
worker->sck = -1;
close_worker_socket (worker);
if (!worker->claimed)
{
zap_worker_in_server (server, worker);
@ -1786,7 +1800,7 @@ static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* b
int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
{
sockaddr_t srv_addr;
int srv_fd, sck_fam, optval;
int srv_fd, sck_fam, optval, xret = 0;
socklen_t srv_len;
pthread_attr_t thr_attr;
@ -1843,10 +1857,16 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
cli_fd = accept(srv_fd, (struct sockaddr*)&cli_addr, &cli_len);
if (cli_fd == -1)
{
if (errno != EINTR || !server->stopreq) set_err_with_syserr (server, errno, "unable to accept worker on socket %d", srv_fd);
if (server->stopreq) break; /* normal termination requested */
if (errno == EINTR) continue; /* interrupted but not termination requested */
set_err_with_syserr (server, errno, "unable to accept worker on socket %d", srv_fd);
xret = -1;
break;
}
hcl_server_logbfmt (server, SERVER_LOGMASK_INFO, "accepted worker - socket %d\n", cli_fd);
worker = alloc_worker(server, cli_fd);
if (pthread_create(&thr, &thr_attr, worker_main, worker) != 0)
{
@ -1858,7 +1878,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
purge_all_workers (server, HCL_SERVER_WORKER_STATE_DEAD);
pthread_attr_destroy (&thr_attr);
return 0;
return xret;
}
void hcl_server_stop (hcl_server_t* server)

157
lib/hcl-tmr.h Normal file
View File

@ -0,0 +1,157 @@
/*
* $Id$
*
Copyright (c) 2016-2018 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.
*/
#ifndef _HCL_TMR_H_
#define _HCL_TMR_H_
#include "hcl-cmn.h"
typedef struct hcl_tmr_t hcl_tmr_t;
typedef struct hcl_tmr_event_t hcl_tmr_event_t;
typedef hcl_oow_t hcl_tmr_index_t;
typedef void (*hcl_tmr_handler_t) (
hcl_tmr_t* tmr,
const hcl_ntime_t* now,
hcl_tmr_event_t* evt
);
typedef void (*hcl_tmr_updater_t) (
hcl_tmr_t* tmr,
hcl_tmr_index_t old_index,
hcl_tmr_index_t new_index,
hcl_tmr_event_t* evt
);
struct hcl_tmr_t
{
hcl_t* hcl;
hcl_oow_t capa;
hcl_oow_t size;
hcl_tmr_event_t* event;
};
struct hcl_tmr_event_t
{
void* ctx; /* primary context pointer */
void* ctx2; /* secondary context pointer */
void* ctx3; /* tertiary context pointer */
hcl_ntime_t when;
hcl_tmr_handler_t handler;
hcl_tmr_updater_t updater;
};
#define HCL_TMR_INVALID_INDEX ((hcl_tmr_index_t)-1)
#define HCL_TMR_SIZE(tmr) ((tmr)->size)
#define HCL_TMR_CAPA(tmr) ((tmr)->capa);
#if defined(__cplusplus)
extern "C" {
#endif
HCL_EXPORT hcl_tmr_t* hcl_tmr_open (
hcl_t* mmgr,
hcl_oow_t xtnsize,
hcl_oow_t capa
);
HCL_EXPORT void hcl_tmr_close (
hcl_tmr_t* tmr
);
HCL_EXPORT int hcl_tmr_init (
hcl_tmr_t* tmr,
hcl_t* mmgr,
hcl_oow_t capa
);
HCL_EXPORT void hcl_tmr_fini (
hcl_tmr_t* tmr
);
/*
HCL_EXPORT hcl_mmgr_t* hcl_tmr_getmmgr (
hcl_tmr_t* tmr
);*/
HCL_EXPORT void* hcl_tmr_getxtn (
hcl_tmr_t* tmr
);
HCL_EXPORT void hcl_tmr_clear (
hcl_tmr_t* tmr
);
/**
* The hcl_tmr_insert() function schedules a new event.
*
* \return #HCL_TMR_INVALID_INDEX on failure, valid index on success.
*/
HCL_EXPORT hcl_tmr_index_t hcl_tmr_insert (
hcl_tmr_t* tmr,
const hcl_tmr_event_t* event
);
HCL_EXPORT hcl_tmr_index_t hcl_tmr_update (
hcl_tmr_t* tmr,
hcl_tmr_index_t index,
const hcl_tmr_event_t* event
);
HCL_EXPORT void hcl_tmr_delete (
hcl_tmr_t* tmr,
hcl_tmr_index_t index
);
HCL_EXPORT int hcl_tmr_fire (
hcl_tmr_t* tmr,
const hcl_ntime_t* tm,
hcl_oow_t* firecnt
);
HCL_EXPORT int hcl_tmr_gettmout (
hcl_tmr_t* tmr,
const hcl_ntime_t* tm,
hcl_ntime_t* tmout
);
/**
* The hcl_tmr_getevent() function returns the
* pointer to the registered event at the given index.
*/
HCL_EXPORT hcl_tmr_event_t* hcl_tmr_getevent (
hcl_tmr_t* tmr,
hcl_tmr_index_t index
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -534,7 +534,6 @@ HCL_EXPORT hcl_uint128_t hcl_hton128 (
);
#endif
#if defined(__cplusplus)
}
#endif

View File

@ -111,6 +111,8 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
if (!hcl->vmprim.free_heap) hcl->vmprim.free_heap = free_heap;
hcl->option.log_mask = ~0u;
hcl->option.log_mask &= ~HCL_LOG_PREFER_JSON;
hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA;
hcl->option.dfl_symtab_size = HCL_DFL_SYMTAB_SIZE;
hcl->option.dfl_sysdic_size = HCL_DFL_SYSDIC_SIZE;

View File

@ -1014,12 +1014,12 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
case 'O': /* object - ignore precision, width, adjustment */
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops;
if (hcl_outfmtobj(hcl, (data->mask & ~HCL_LOG_PREFER_JSON), arg, outbfmt) <= -1) goto oops;
break;
case 'J':
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
if (hcl_outfmtobj(hcl, data->mask | HCL_LOG_PREFER_JSON, arg, outbfmt) <= -1) goto oops;
if (hcl_outfmtobj(hcl, (data->mask | HCL_LOG_PREFER_JSON), arg, outbfmt) <= -1) goto oops;
break;
number:

View File

@ -585,11 +585,11 @@ static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_lis
}
case 'O': /* object - ignore precision, width, adjustment */
if (hcl_outfmtobj(hcl, data->mask, va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
if (hcl_outfmtobj(hcl, (data->mask & ~HCL_LOG_PREFER_JSON), va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
break;
case 'J':
if (hcl_outfmtobj(hcl, data->mask | HCL_LOG_PREFER_JSON, va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
if (hcl_outfmtobj(hcl, (data->mask | HCL_LOG_PREFER_JSON), va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
break;
#if 0

279
lib/tmr.c Normal file
View File

@ -0,0 +1,279 @@
/*
* $Id$
*
Copyright (c) 2016-2018 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 <hcl-tmr.h>
#include "hcl-prv.h"
#define HEAP_PARENT(x) (((x) - 1) / 2)
#define HEAP_LEFT(x) ((x) * 2 + 1)
#define HEAP_RIGHT(x) ((x) * 2 + 2)
#define YOUNGER_THAN(x,y) (HCL_CMPNTIME(&(x)->when, &(y)->when) < 0)
hcl_tmr_t* hcl_tmr_open (hcl_t* hcl, hcl_oow_t xtnsize, hcl_oow_t capa)
{
hcl_tmr_t* tmr;
tmr = HCL_MMGR_ALLOC(hcl->mmgr, HCL_SIZEOF(hcl_tmr_t) + xtnsize);
if (tmr)
{
if (hcl_tmr_init(tmr, hcl, capa) <= -1)
{
HCL_MMGR_FREE (hcl->mmgr, tmr);
return HCL_NULL;
}
else HCL_MEMSET (tmr + 1, 0, xtnsize);
}
return tmr;
}
void hcl_tmr_close (hcl_tmr_t* tmr)
{
hcl_tmr_fini (tmr);
HCL_MMGR_FREE (tmr->hcl->mmgr, tmr);
}
int hcl_tmr_init (hcl_tmr_t* tmr, hcl_t* hcl, hcl_oow_t capa)
{
hcl_tmr_event_t* tmp;
HCL_MEMSET (tmr, 0, HCL_SIZEOF(*tmr));
if (capa <= 0) capa = 1;
tmp = HCL_MMGR_ALLOC (hcl->mmgr, capa * HCL_SIZEOF(*tmp));
if (tmp == HCL_NULL) return -1;
tmr->hcl = hcl;
tmr->capa = capa;
tmr->event = tmp;
return 0;
}
void hcl_tmr_fini (hcl_tmr_t* tmr)
{
hcl_tmr_clear (tmr);
if (tmr->event) HCL_MMGR_FREE (tmr->hcl->mmgr, tmr->event);
}
/*
hcl_mmgr_t* hcl_tmr_getmmgr (hcl_tmr_t* tmr)
{
return tmr->hcl->mmgr;
}*/
void* hcl_tmr_getxtn (hcl_tmr_t* tmr)
{
return (void*)(tmr + 1);
}
void hcl_tmr_clear (hcl_tmr_t* tmr)
{
while (tmr->size > 0) hcl_tmr_delete (tmr, 0);
}
static hcl_tmr_index_t sift_up (hcl_tmr_t* tmr, hcl_tmr_index_t index, int notify)
{
hcl_oow_t parent;
parent = HEAP_PARENT(index);
if (index > 0 && YOUNGER_THAN(&tmr->event[index], &tmr->event[parent]))
{
hcl_tmr_event_t item;
hcl_oow_t old_index;
item = tmr->event[index];
old_index = index;
do
{
/* move down the parent to my current position */
tmr->event[index] = tmr->event[parent];
tmr->event[index].updater (tmr, parent, index, &tmr->event[index]);
/* traverse up */
index = parent;
parent = HEAP_PARENT(parent);
}
while (index > 0 && YOUNGER_THAN(&item, &tmr->event[parent]));
/* we send no notification if the item is added with hcl_tmr_insert()
* or updated with hcl_tmr_update(). the caller of these functions
* must rely on the return value. */
tmr->event[index] = item;
if (notify && index != old_index)
tmr->event[index].updater (tmr, old_index, index, &tmr->event[index]);
}
return index;
}
static hcl_tmr_index_t sift_down (hcl_tmr_t* tmr, hcl_tmr_index_t index, int notify)
{
hcl_oow_t base = tmr->size / 2;
if (index < base) /* at least 1 child is under the 'index' position */
{
hcl_tmr_event_t item;
hcl_oow_t old_index;
item = tmr->event[index];
old_index = index;
do
{
hcl_oow_t left, right, younger;
left = HEAP_LEFT(index);
right = HEAP_RIGHT(index);
if (right < tmr->size && YOUNGER_THAN(&tmr->event[right], &tmr->event[left]))
{
younger = right;
}
else
{
younger = left;
}
if (YOUNGER_THAN(&item, &tmr->event[younger])) break;
tmr->event[index] = tmr->event[younger];
tmr->event[index].updater (tmr, younger, index, &tmr->event[index]);
index = younger;
}
while (index < base);
tmr->event[index] = item;
if (notify && index != old_index)
tmr->event[index].updater (tmr, old_index, index, &tmr->event[index]);
}
return index;
}
void hcl_tmr_delete (hcl_tmr_t* tmr, hcl_tmr_index_t index)
{
hcl_tmr_event_t item;
HCL_ASSERT (tmr->hcl, index < tmr->size);
item = tmr->event[index];
tmr->event[index].updater (tmr, index, HCL_TMR_INVALID_INDEX, &tmr->event[index]);
tmr->size = tmr->size - 1;
if (tmr->size > 0 && index != tmr->size)
{
tmr->event[index] = tmr->event[tmr->size];
tmr->event[index].updater (tmr, tmr->size, index, &tmr->event[index]);
YOUNGER_THAN(&tmr->event[index], &item)? sift_up(tmr, index, 1): sift_down(tmr, index, 1);
}
}
hcl_tmr_index_t hcl_tmr_insert (hcl_tmr_t* tmr, const hcl_tmr_event_t* event)
{
hcl_tmr_index_t index = tmr->size;
if (index >= tmr->capa)
{
hcl_tmr_event_t* tmp;
hcl_oow_t new_capa;
HCL_ASSERT (tmr->hcl, tmr->capa >= 1);
new_capa = tmr->capa * 2;
tmp = HCL_MMGR_REALLOC (tmr->hcl->mmgr, tmr->event, new_capa * HCL_SIZEOF(*tmp));
if (tmp == HCL_NULL) return HCL_TMR_INVALID_INDEX;
tmr->event = tmp;
tmr->capa = new_capa;
}
tmr->size = tmr->size + 1;
tmr->event[index] = *event;
return sift_up (tmr, index, 0);
}
hcl_tmr_index_t hcl_tmr_update (hcl_tmr_t* tmr, hcl_oow_t index, const hcl_tmr_event_t* event)
{
hcl_tmr_event_t item;
item = tmr->event[index];
tmr->event[index] = *event;
return YOUNGER_THAN(event, &item)? sift_up (tmr, index, 0): sift_down (tmr, index, 0);
}
int hcl_tmr_fire (hcl_tmr_t* tmr, const hcl_ntime_t* tm, hcl_oow_t* firecnt)
{
hcl_ntime_t now;
hcl_tmr_event_t event;
hcl_oow_t fire_count = 0;
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
/*else if (hcl_gettime(&now) <= -1) return -1;*/
tmr->hcl->vmprim.vm_gettime (tmr->hcl, &now);
while (tmr->size > 0)
{
if (HCL_CMPNTIME(&tmr->event[0].when, &now) > 0) break;
event = tmr->event[0];
hcl_tmr_delete (tmr, 0); /* remove the registered event structure */
fire_count++;
event.handler (tmr, &now, &event); /* then fire the event */
}
if (firecnt) *firecnt = fire_count;
return 0;
}
int hcl_tmr_gettmout (hcl_tmr_t* tmr, const hcl_ntime_t* tm, hcl_ntime_t* tmout)
{
hcl_ntime_t now;
/* time-out can't be calculated when there's no event scheduled */
if (tmr->size <= 0) return -1;
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
/*else if (hcl_gettime(&now) <= -1) return -1;*/
tmr->hcl->vmprim.vm_gettime (tmr->hcl, &now);
HCL_SUBNTIME (&tmr->event[0].when, &now, tmout);
if (tmout->sec < 0) HCL_CLEARNTIME (tmout);
return 0;
}
hcl_tmr_event_t* hcl_tmr_getevent (hcl_tmr_t* tmr, hcl_tmr_index_t index)
{
return (index < 0 || index >= tmr->size)? HCL_NULL: &tmr->event[index];
}

View File

@ -376,7 +376,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@