added timer functions
This commit is contained in:
		| @ -353,7 +353,6 @@ pdfdir = @pdfdir@ | |||||||
| prefix = @prefix@ | prefix = @prefix@ | ||||||
| program_transform_name = @program_transform_name@ | program_transform_name = @program_transform_name@ | ||||||
| psdir = @psdir@ | psdir = @psdir@ | ||||||
| runstatedir = @runstatedir@ |  | ||||||
| sbindir = @sbindir@ | sbindir = @sbindir@ | ||||||
| sharedstatedir = @sharedstatedir@ | sharedstatedir = @sharedstatedir@ | ||||||
| srcdir = @srcdir@ | srcdir = @srcdir@ | ||||||
| @ -584,7 +583,7 @@ distdir: $(DISTFILES) | |||||||
| 	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ | 	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ | ||||||
| 	|| chmod -R a+r "$(distdir)" | 	|| chmod -R a+r "$(distdir)" | ||||||
| dist-gzip: 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) | 	$(am__post_remove_distdir) | ||||||
|  |  | ||||||
| dist-bzip2: distdir | dist-bzip2: distdir | ||||||
| @ -610,7 +609,7 @@ dist-shar: distdir | |||||||
| 	@echo WARNING: "Support for shar distribution archives is" \ | 	@echo WARNING: "Support for shar distribution archives is" \ | ||||||
| 	               "deprecated." >&2 | 	               "deprecated." >&2 | ||||||
| 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&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) | 	$(am__post_remove_distdir) | ||||||
|  |  | ||||||
| dist-zip: distdir | dist-zip: distdir | ||||||
| @ -628,7 +627,7 @@ dist dist-all: | |||||||
| distcheck: dist | distcheck: dist | ||||||
| 	case '$(DIST_ARCHIVES)' in \ | 	case '$(DIST_ARCHIVES)' in \ | ||||||
| 	*.tar.gz*) \ | 	*.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*) \ | 	*.tar.bz2*) \ | ||||||
| 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ | 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ | ||||||
| 	*.tar.lz*) \ | 	*.tar.lz*) \ | ||||||
| @ -638,7 +637,7 @@ distcheck: dist | |||||||
| 	*.tar.Z*) \ | 	*.tar.Z*) \ | ||||||
| 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ | 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ | ||||||
| 	*.shar.gz*) \ | 	*.shar.gz*) \ | ||||||
| 	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ | 	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ | ||||||
| 	*.zip*) \ | 	*.zip*) \ | ||||||
| 	  unzip $(distdir).zip ;;\ | 	  unzip $(distdir).zip ;;\ | ||||||
| 	esac | 	esac | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								hcl/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								hcl/configure
									
									
									
									
										vendored
									
									
								
							| @ -779,7 +779,6 @@ infodir | |||||||
| docdir | docdir | ||||||
| oldincludedir | oldincludedir | ||||||
| includedir | includedir | ||||||
| runstatedir |  | ||||||
| localstatedir | localstatedir | ||||||
| sharedstatedir | sharedstatedir | ||||||
| sysconfdir | sysconfdir | ||||||
| @ -872,7 +871,6 @@ datadir='${datarootdir}' | |||||||
| sysconfdir='${prefix}/etc' | sysconfdir='${prefix}/etc' | ||||||
| sharedstatedir='${prefix}/com' | sharedstatedir='${prefix}/com' | ||||||
| localstatedir='${prefix}/var' | localstatedir='${prefix}/var' | ||||||
| runstatedir='${localstatedir}/run' |  | ||||||
| includedir='${prefix}/include' | includedir='${prefix}/include' | ||||||
| oldincludedir='/usr/include' | oldincludedir='/usr/include' | ||||||
| docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' | docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' | ||||||
| @ -1125,15 +1123,6 @@ do | |||||||
|   | -silent | --silent | --silen | --sile | --sil) |   | -silent | --silent | --silen | --sile | --sil) | ||||||
|     silent=yes ;; |     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) |   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) | ||||||
|     ac_prev=sbindir ;; |     ac_prev=sbindir ;; | ||||||
|   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ |   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | ||||||
| @ -1271,7 +1260,7 @@ fi | |||||||
| for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \ | for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \ | ||||||
| 		datadir sysconfdir sharedstatedir localstatedir includedir \ | 		datadir sysconfdir sharedstatedir localstatedir includedir \ | ||||||
| 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ | 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ | ||||||
| 		libdir localedir mandir runstatedir | 		libdir localedir mandir | ||||||
| do | do | ||||||
|   eval ac_val=\$$ac_var |   eval ac_val=\$$ac_var | ||||||
|   # Remove trailing slashes. |   # Remove trailing slashes. | ||||||
| @ -1424,7 +1413,6 @@ Fine tuning of the installation directories: | |||||||
|   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc] |   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc] | ||||||
|   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com] |   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com] | ||||||
|   --localstatedir=DIR     modifiable single-machine data [PREFIX/var] |   --localstatedir=DIR     modifiable single-machine data [PREFIX/var] | ||||||
|   --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run] |  | ||||||
|   --libdir=DIR            object code libraries [EPREFIX/lib] |   --libdir=DIR            object code libraries [EPREFIX/lib] | ||||||
|   --includedir=DIR        C header files [PREFIX/include] |   --includedir=DIR        C header files [PREFIX/include] | ||||||
|   --oldincludedir=DIR     C header files for non-gcc [/usr/include] |   --oldincludedir=DIR     C header files for non-gcc [/usr/include] | ||||||
|  | |||||||
| @ -36,6 +36,7 @@ pkginclude_HEADERS = \ | |||||||
| 	hcl-cfg.h \ | 	hcl-cfg.h \ | ||||||
| 	hcl-cmn.h \ | 	hcl-cmn.h \ | ||||||
| 	hcl-rbt.h \ | 	hcl-rbt.h \ | ||||||
|  | 	hcl-tmr.h \ | ||||||
| 	hcl-utl.h \ | 	hcl-utl.h \ | ||||||
| 	hcl.h | 	hcl.h | ||||||
|  |  | ||||||
| @ -63,6 +64,7 @@ libhcl_la_SOURCES = \ | |||||||
| 	rbt.c \ | 	rbt.c \ | ||||||
| 	read.c \ | 	read.c \ | ||||||
| 	sym.c \ | 	sym.c \ | ||||||
|  | 	tmr.c \ | ||||||
| 	utf8.c \ | 	utf8.c \ | ||||||
| 	utl.c  | 	utl.c  | ||||||
| libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) | libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) | ||||||
|  | |||||||
| @ -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-hcl.lo libhcl_la-heap.lo libhcl_la-logfmt.lo \ | ||||||
| 	libhcl_la-obj.lo libhcl_la-opt.lo libhcl_la-prim.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-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) | libhcl_la_OBJECTS = $(am_libhcl_la_OBJECTS) | ||||||
| AM_V_lt = $(am__v_lt_@AM_V@) | AM_V_lt = $(am__v_lt_@AM_V@) | ||||||
| am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) | am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) | ||||||
| @ -399,7 +400,6 @@ pdfdir = @pdfdir@ | |||||||
| prefix = @prefix@ | prefix = @prefix@ | ||||||
| program_transform_name = @program_transform_name@ | program_transform_name = @program_transform_name@ | ||||||
| psdir = @psdir@ | psdir = @psdir@ | ||||||
| runstatedir = @runstatedir@ |  | ||||||
| sbindir = @sbindir@ | sbindir = @sbindir@ | ||||||
| sharedstatedir = @sharedstatedir@ | sharedstatedir = @sharedstatedir@ | ||||||
| srcdir = @srcdir@ | srcdir = @srcdir@ | ||||||
| @ -428,6 +428,7 @@ pkginclude_HEADERS = \ | |||||||
| 	hcl-cfg.h \ | 	hcl-cfg.h \ | ||||||
| 	hcl-cmn.h \ | 	hcl-cmn.h \ | ||||||
| 	hcl-rbt.h \ | 	hcl-rbt.h \ | ||||||
|  | 	hcl-tmr.h \ | ||||||
| 	hcl-utl.h \ | 	hcl-utl.h \ | ||||||
| 	hcl.h | 	hcl.h | ||||||
|  |  | ||||||
| @ -455,6 +456,7 @@ libhcl_la_SOURCES = \ | |||||||
| 	rbt.c \ | 	rbt.c \ | ||||||
| 	read.c \ | 	read.c \ | ||||||
| 	sym.c \ | 	sym.c \ | ||||||
|  | 	tmr.c \ | ||||||
| 	utf8.c \ | 	utf8.c \ | ||||||
| 	utl.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-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-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-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-utf8.Plo@am__quote@ | ||||||
| @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utl.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@ | @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@ | @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 | @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 | 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_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 | @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-utf8.Tpo $(DEPDIR)/libhcl_la-utf8.Plo | ||||||
|  | |||||||
| @ -947,7 +947,8 @@ typedef union sockaddr_t sockaddr_t; | |||||||
| #include "sa-utl.h" | #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) | 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 | 			/* error occurred inside the worker thread shouldn't affect the error information | ||||||
| 			 * in the server object. so here, i just log a message */ | 			 * 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;  | 			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)); | 		tmp = (hcl_ooch_t*)HCL_MMGR_REALLOC(proto->worker->server->mmgr, proto->tok.ptr, capa * HCL_SIZEOF(*tmp)); | ||||||
| 		if (!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; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -1334,7 +1335,7 @@ static int get_token (hcl_server_proto_t* proto) | |||||||
| 			GET_CHAR_TO(proto, c); | 			GET_CHAR_TO(proto, c); | ||||||
| 			if (!is_alphachar(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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -1351,7 +1352,7 @@ static int get_token (hcl_server_proto_t* proto) | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		default: | 		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 -1; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -1370,7 +1371,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) | |||||||
| 		case HCL_SERVER_PROTO_TOKEN_EOF: | 		case HCL_SERVER_PROTO_TOKEN_EOF: | ||||||
| 			if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -1380,21 +1381,21 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) | |||||||
| 		case HCL_SERVER_PROTO_TOKEN_EXIT: | 		case HCL_SERVER_PROTO_TOKEN_EXIT: | ||||||
| 			if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (get_token(proto) <= -1) return -1; | 			if (get_token(proto) <= -1) return -1; | ||||||
| 			if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
| 			 | 			 | ||||||
| 			hcl_server_proto_start_reply (proto); | 			hcl_server_proto_start_reply (proto); | ||||||
| 			if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)  | 			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 -1; | ||||||
| 			} | 			} | ||||||
| 			return 0; | 			return 0; | ||||||
| @ -1402,14 +1403,14 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) | |||||||
| 		case HCL_SERVER_PROTO_TOKEN_BEGIN: | 		case HCL_SERVER_PROTO_TOKEN_BEGIN: | ||||||
| 			if (proto->req.state != HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (get_token(proto) <= -1) return -1; | 			if (get_token(proto) <= -1) return -1; | ||||||
| 			if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) | 			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; | 				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) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (get_token(proto) <= -1) return -1; | 			if (get_token(proto) <= -1) return -1; | ||||||
| 			if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) | 			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; | 				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; | 			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)  | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -1455,20 +1456,20 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) | |||||||
| 			obj = hcl_read(proto->hcl); | 			obj = hcl_read(proto->hcl); | ||||||
| 			if (!obj) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (get_token(proto) <= -1) return -1; | 			if (get_token(proto) <= -1) return -1; | ||||||
| 			if (proto->tok.type != HCL_SERVER_PROTO_TOKEN_NL) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (hcl_compile(proto->hcl, obj) <= -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; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -1478,7 +1479,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) | |||||||
| 				obj = hcl_execute(proto->hcl); | 				obj = hcl_execute(proto->hcl); | ||||||
| 				if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1)  | 				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; | 					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) | 			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; | 				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) | 			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; | 				return -1; | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		default: | 		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; | 			return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -1597,9 +1598,26 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t*  server, int cli_sck) | |||||||
| 	return worker; | 	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) | 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); | 	HCL_MMGR_FREE (worker->server->mmgr, worker); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -1671,11 +1689,7 @@ static void* worker_main (void* ctx) | |||||||
| 	worker->proto = HCL_NULL; | 	worker->proto = HCL_NULL; | ||||||
|  |  | ||||||
| 	pthread_mutex_lock (&server->worker_mutex); | 	pthread_mutex_lock (&server->worker_mutex); | ||||||
|  | 	close_worker_socket (worker);  | ||||||
| 	/* close connection before free_client() is called */ |  | ||||||
| 	close (worker->sck); |  | ||||||
| 	worker->sck = -1; |  | ||||||
|  |  | ||||||
| 	if (!worker->claimed) | 	if (!worker->claimed) | ||||||
| 	{ | 	{ | ||||||
| 		zap_worker_in_server (server, worker); | 		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) | int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) | ||||||
| { | { | ||||||
| 	sockaddr_t srv_addr; | 	sockaddr_t srv_addr; | ||||||
| 	int srv_fd, sck_fam, optval; | 	int srv_fd, sck_fam, optval, xret = 0; | ||||||
| 	socklen_t srv_len; | 	socklen_t srv_len; | ||||||
| 	pthread_attr_t thr_attr; | 	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); | 		cli_fd = accept(srv_fd, (struct sockaddr*)&cli_addr, &cli_len); | ||||||
| 		if (cli_fd == -1) | 		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; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		hcl_server_logbfmt (server, SERVER_LOGMASK_INFO, "accepted worker - socket %d\n", cli_fd); | ||||||
|  |  | ||||||
| 		worker = alloc_worker(server, cli_fd); | 		worker = alloc_worker(server, cli_fd); | ||||||
| 		if (pthread_create(&thr, &thr_attr, worker_main, worker) != 0) | 		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); | 	purge_all_workers (server, HCL_SERVER_WORKER_STATE_DEAD); | ||||||
|  |  | ||||||
| 	pthread_attr_destroy (&thr_attr); | 	pthread_attr_destroy (&thr_attr); | ||||||
| 	return 0; | 	return xret; | ||||||
| } | } | ||||||
|  |  | ||||||
| void hcl_server_stop (hcl_server_t* server) | void hcl_server_stop (hcl_server_t* server) | ||||||
|  | |||||||
							
								
								
									
										157
									
								
								hcl/lib/hcl-tmr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								hcl/lib/hcl-tmr.h
									
									
									
									
									
										Normal 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 | ||||||
| @ -534,7 +534,6 @@ HCL_EXPORT hcl_uint128_t hcl_hton128 ( | |||||||
| ); | ); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -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; | 	if (!hcl->vmprim.free_heap) hcl->vmprim.free_heap = free_heap; | ||||||
|  |  | ||||||
| 	hcl->option.log_mask = ~0u; | 	hcl->option.log_mask = ~0u; | ||||||
|  | 	hcl->option.log_mask &= ~HCL_LOG_PREFER_JSON; | ||||||
|  |  | ||||||
| 	hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA; | 	hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA; | ||||||
| 	hcl->option.dfl_symtab_size = HCL_DFL_SYMTAB_SIZE; | 	hcl->option.dfl_symtab_size = HCL_DFL_SYMTAB_SIZE; | ||||||
| 	hcl->option.dfl_sysdic_size = HCL_DFL_SYSDIC_SIZE; | 	hcl->option.dfl_sysdic_size = HCL_DFL_SYSDIC_SIZE; | ||||||
|  | |||||||
| @ -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 */ | 		case 'O': /* object - ignore precision, width, adjustment */ | ||||||
| 			GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg); | 			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; | 			break; | ||||||
|  |  | ||||||
| 		case 'J': | 		case 'J': | ||||||
| 			GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg); | 			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; | 			break; | ||||||
|  |  | ||||||
| 		number: | 		number: | ||||||
|  | |||||||
| @ -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 */ | 		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; | 			break; | ||||||
|  |  | ||||||
| 		case 'J': | 		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; | 			break; | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
|  | |||||||
							
								
								
									
										279
									
								
								hcl/lib/tmr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								hcl/lib/tmr.c
									
									
									
									
									
										Normal 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]; | ||||||
|  | } | ||||||
| @ -376,7 +376,6 @@ pdfdir = @pdfdir@ | |||||||
| prefix = @prefix@ | prefix = @prefix@ | ||||||
| program_transform_name = @program_transform_name@ | program_transform_name = @program_transform_name@ | ||||||
| psdir = @psdir@ | psdir = @psdir@ | ||||||
| runstatedir = @runstatedir@ |  | ||||||
| sbindir = @sbindir@ | sbindir = @sbindir@ | ||||||
| sharedstatedir = @sharedstatedir@ | sharedstatedir = @sharedstatedir@ | ||||||
| srcdir = @srcdir@ | srcdir = @srcdir@ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user