diff --git a/Makefile.in b/Makefile.in index ea0c943..365416a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/configure b/configure index 1e041e0..76cb776 100755 --- a/configure +++ b/configure @@ -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] diff --git a/lib/Makefile.am b/lib/Makefile.am index 7c15928..b5e9519 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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) diff --git a/lib/Makefile.in b/lib/Makefile.in index 44dea0a..9ddb705 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -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 diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 8b1dd20..1ed7b8e 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -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) diff --git a/lib/hcl-tmr.h b/lib/hcl-tmr.h new file mode 100644 index 0000000..45f6246 --- /dev/null +++ b/lib/hcl-tmr.h @@ -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 diff --git a/lib/hcl-utl.h b/lib/hcl-utl.h index 7b8a22f..1637091 100644 --- a/lib/hcl-utl.h +++ b/lib/hcl-utl.h @@ -534,7 +534,6 @@ HCL_EXPORT hcl_uint128_t hcl_hton128 ( ); #endif - #if defined(__cplusplus) } #endif diff --git a/lib/hcl.c b/lib/hcl.c index 93bee83..a1119ec 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -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; diff --git a/lib/logfmt.c b/lib/logfmt.c index 1c8bcbd..3bc9127 100644 --- a/lib/logfmt.c +++ b/lib/logfmt.c @@ -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: diff --git a/lib/logfmtv.h b/lib/logfmtv.h index 9d86ad7..a64ad57 100644 --- a/lib/logfmtv.h +++ b/lib/logfmtv.h @@ -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 diff --git a/lib/tmr.c b/lib/tmr.c new file mode 100644 index 0000000..8717863 --- /dev/null +++ b/lib/tmr.c @@ -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 +#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]; +} diff --git a/mod/Makefile.in b/mod/Makefile.in index 40b1ca0..1970289 100644 --- a/mod/Makefile.in +++ b/mod/Makefile.in @@ -376,7 +376,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@