enhanced the log_write callback to use as few write system calls as possible.

changed the hcl server to raise an error if .SCRIPT is not followed by actual script text on the same line
This commit is contained in:
hyung-hwan 2018-03-16 16:20:40 +00:00
parent 0b7acc1fd8
commit 36ee74f0ec
6 changed files with 198 additions and 30 deletions

4
configure vendored
View File

@ -18220,7 +18220,7 @@ fi
done done
for ac_header in dlfcn.h ltdl.h sys/mman.h for ac_header in dlfcn.h ltdl.h sys/mman.h sys/uio.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -18296,7 +18296,7 @@ _ACEOF
fi fi
done done
for ac_func in isatty mmap munmap for ac_func in isatty mmap munmap readv writev
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -120,7 +120,7 @@ dnl check header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h]) AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h])
AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h])
AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h]) AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h sys/uio.h])
dnl check data types dnl check data types
dnl AC_CHECK_TYPE([wchar_t], dnl AC_CHECK_TYPE([wchar_t],
@ -136,7 +136,7 @@ AC_CHECK_FUNCS([backtrace backtrace_symbols])
AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext]) AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext])
AC_CHECK_FUNCS([clock_nanosleep nanosleep usleep]) AC_CHECK_FUNCS([clock_nanosleep nanosleep usleep])
AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf]) AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf])
AC_CHECK_FUNCS([isatty mmap munmap]) AC_CHECK_FUNCS([isatty mmap munmap readv writev])
save_LIBS="$LIBS" save_LIBS="$LIBS"
AC_SEARCH_LIBS([dlopen], [dl dld], [ AC_SEARCH_LIBS([dlopen], [dl dld], [

View File

@ -117,6 +117,9 @@
/* Define to 1 if you have the `quadmath_snprintf' function. */ /* Define to 1 if you have the `quadmath_snprintf' function. */
#undef HAVE_QUADMATH_SNPRINTF #undef HAVE_QUADMATH_SNPRINTF
/* Define to 1 if you have the `readv' function. */
#undef HAVE_READV
/* Define to 1 if you have the `roundq' function. */ /* Define to 1 if you have the `roundq' function. */
#undef HAVE_ROUNDQ #undef HAVE_ROUNDQ
@ -183,6 +186,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H #undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the `tanhq' function. */ /* Define to 1 if you have the `tanhq' function. */
#undef HAVE_TANHQ #undef HAVE_TANHQ
@ -213,6 +219,9 @@
/* Define to 1 if you have the <wctype.h> header file. */ /* Define to 1 if you have the <wctype.h> header file. */
#undef HAVE_WCTYPE_H #undef HAVE_WCTYPE_H
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* Define to 1 if you have the `_vsnprintf' function. */ /* Define to 1 if you have the `_vsnprintf' function. */
#undef HAVE__VSNPRINTF #undef HAVE__VSNPRINTF

View File

@ -32,8 +32,9 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#define TOKEN_NAME_ALIGN 64 #define HCL_SERVER_TOKEN_NAME_ALIGN 64
#define WID_MAP_ALIGN 512 #define HCL_SERVER_WID_MAP_ALIGN 512
#define HCL_SERVER_PROTO_REPLY_BUF_SIZE 1300
#if defined(_WIN32) #if defined(_WIN32)
# include <windows.h> # include <windows.h>
@ -86,6 +87,9 @@
# if defined(HAVE_SYS_MMAN_H) # if defined(HAVE_SYS_MMAN_H)
# include <sys/mman.h> # include <sys/mman.h>
# endif # endif
# if defined(HAVE_SYS_UIO_H)
# include <sys/uio.h>
# endif
# include <unistd.h> # include <unistd.h>
# include <fcntl.h> # include <fcntl.h>
@ -93,7 +97,6 @@
# include <sys/socket.h> # include <sys/socket.h>
# include <netinet/in.h> # include <netinet/in.h>
# include <pthread.h> # include <pthread.h>
# include <sys/uio.h>
# include <poll.h> # include <poll.h>
#endif #endif
@ -183,8 +186,6 @@ enum hcl_server_proto_req_state_t
HCL_SERVER_PROTO_REQ_IN_BLOCK_LEVEL HCL_SERVER_PROTO_REQ_IN_BLOCK_LEVEL
}; };
#define HCL_SERVER_PROTO_REPLY_BUF_SIZE 1300
enum hcl_server_proto_reply_type_t enum hcl_server_proto_reply_type_t
{ {
HCL_SERVER_PROTO_REPLY_SIMPLE = 0, HCL_SERVER_PROTO_REPLY_SIMPLE = 0,
@ -1278,7 +1279,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c)
hcl_ooch_t* tmp; hcl_ooch_t* tmp;
hcl_oow_t capa; hcl_oow_t capa;
capa = HCL_ALIGN_POW2(proto->tok.len + 1, TOKEN_NAME_ALIGN); capa = HCL_ALIGN_POW2(proto->tok.len + 1, HCL_SERVER_TOKEN_NAME_ALIGN);
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)
{ {
@ -1582,6 +1583,18 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
case HCL_SERVER_PROTO_TOKEN_SCRIPT: case HCL_SERVER_PROTO_TOKEN_SCRIPT:
{ {
hcl_oop_t obj; hcl_oop_t obj;
hcl_ooci_t c;
/* do a special check bypassing get_token(). it checks if the script contents
* come on the same line as .SCRIPT */
GET_CHAR_TO (proto, c);
while (is_spacechar(c)) GET_CHAR_TO (proto, c);
if (c == HCL_OOCI_EOF || c == '\n')
{
HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No contents on the .SCRIPT line\n");
return -1;
}
UNGET_LAST_CHAR (proto);
if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) hcl_reset(proto->hcl); if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) hcl_reset(proto->hcl);
@ -1785,7 +1798,7 @@ static HCL_INLINE int prepare_to_acquire_wid (hcl_server_t* server)
HCL_ASSERT (server->dummy_hcl, server->wid_map.free_first == HCL_SERVER_WID_INVALID); HCL_ASSERT (server->dummy_hcl, server->wid_map.free_first == HCL_SERVER_WID_INVALID);
HCL_ASSERT (server->dummy_hcl, server->wid_map.free_last == HCL_SERVER_WID_INVALID); HCL_ASSERT (server->dummy_hcl, server->wid_map.free_last == HCL_SERVER_WID_INVALID);
new_capa = HCL_ALIGN_POW2(server->wid_map.capa + 1, WID_MAP_ALIGN); new_capa = HCL_ALIGN_POW2(server->wid_map.capa + 1, HCL_SERVER_WID_MAP_ALIGN);
if (new_capa > HCL_SERVER_WID_MAX) if (new_capa > HCL_SERVER_WID_MAX)
{ {
if (server->wid_map.capa >= HCL_SERVER_WID_MAX) if (server->wid_map.capa >= HCL_SERVER_WID_MAX)
@ -2029,7 +2042,6 @@ void hcl_server_logufmt (hcl_server_t* server, unsigned int mask, const hcl_uch_
va_end (ap); va_end (ap);
} }
static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* bfmt, ...) static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* bfmt, ...)
{ {
hcl_t* hcl = server->dummy_hcl; hcl_t* hcl = server->dummy_hcl;

View File

@ -145,6 +145,12 @@ struct xtn_t
unsigned int logmask; unsigned int logmask;
int logfd_istty; int logfd_istty;
struct
{
hcl_bch_t buf[4096];
hcl_oow_t len;
} logbuf;
int reader_istty; int reader_istty;
hcl_oop_t sym_errstr; hcl_oop_t sym_errstr;
@ -511,7 +517,7 @@ static void free_heap (hcl_t* hcl, void* ptr)
#endif #endif
} }
static int write_all (int fd, const char* ptr, hcl_oow_t len) static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len)
{ {
while (len > 0) while (len > 0)
{ {
@ -545,6 +551,71 @@ static int write_all (int fd, const char* ptr, hcl_oow_t len)
return 0; return 0;
} }
static int write_log (hcl_t* hcl, const hcl_bch_t* ptr, hcl_oow_t len)
{
xtn_t* xtn;
xtn = hcl_getxtn(hcl);
while (len > 0)
{
if (xtn->logbuf.len > 0)
{
hcl_oow_t rcapa, cplen;
rcapa = HCL_COUNTOF(xtn->logbuf.buf) - xtn->logbuf.len;
cplen = (len >= rcapa)? rcapa: len;
memcpy (&xtn->logbuf.buf[xtn->logbuf.len], ptr, cplen);
xtn->logbuf.len += cplen;
ptr += cplen;
len -= cplen;
if (xtn->logbuf.len >= HCL_COUNTOF(xtn->logbuf.buf))
{
int n;
n = write_all(xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len);
xtn->logbuf.len = 0;
if (n <= -1) return -1;
}
}
else
{
hcl_oow_t rcapa;
rcapa = HCL_COUNTOF(xtn->logbuf.buf);
if (len >= rcapa)
{
if (write_all(xtn->logfd, ptr, rcapa) <= -1) return -1;
ptr += rcapa;
len -= rcapa;
}
else
{
memcpy (xtn->logbuf.buf, ptr, len);
xtn->logbuf.len += len;
ptr += len;
len -= len;
}
}
}
return 0;
}
static void flush_log (hcl_t* hcl)
{
xtn_t* xtn;
xtn = hcl_getxtn(hcl);
if (xtn->logbuf.len > 0)
{
write_all (xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len);
xtn->logbuf.len = 0;
}
}
static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len) static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
{ {
hcl_bch_t buf[256]; hcl_bch_t buf[256];
@ -604,14 +675,14 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl
tslen = 25; tslen = 25;
} }
#endif #endif
write_all (logfd, ts, tslen); write_log (hcl, ts, tslen);
} }
if (xtn->logfd_istty) if (xtn->logfd_istty)
{ {
if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); if (mask & HCL_LOG_FATAL) write_log (hcl, "\x1B[1;31m", 7);
else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); else if (mask & HCL_LOG_ERROR) write_log (hcl, "\x1B[1;32m", 7);
else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); else if (mask & HCL_LOG_WARN) write_log (hcl, "\x1B[1;33m", 7);
} }
#if defined(HCL_OOCH_IS_UCH) #if defined(HCL_OOCH_IS_UCH)
@ -633,7 +704,7 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl
HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */ HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */
/* attempt to write all converted characters */ /* attempt to write all converted characters */
if (write_all (logfd, buf, bcslen) <= -1) break; if (write_log (hcl, buf, bcslen) <= -1) break;
if (n == 0) break; if (n == 0) break;
else else
@ -649,13 +720,15 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl
} }
} }
#else #else
write_all (logfd, msg, len); write_log (hcl, msg, len);
#endif #endif
if (xtn->logfd_istty) if (xtn->logfd_istty)
{ {
if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_log (hcl, "\x1B[0m", 4);
} }
flush_log (hcl);
} }

View File

@ -43,6 +43,9 @@
#if defined(HAVE_SIGNAL_H) #if defined(HAVE_SIGNAL_H)
# include <signal.h> # include <signal.h>
#endif #endif
#if defined(HAVE_SYS_UIO_H)
# include <sys/uio.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
@ -55,6 +58,12 @@ struct server_xtn_t
int logfd; int logfd;
unsigned int logmask; unsigned int logmask;
int logfd_istty; int logfd_istty;
struct
{
hcl_bch_t buf[4096];
hcl_oow_t len;
} logbuf;
}; };
/* ========================================================================= */ /* ========================================================================= */
@ -83,7 +92,7 @@ static hcl_mmgr_t sys_mmgr =
}; };
/* ========================================================================= */ /* ========================================================================= */
static int write_all (int fd, const char* ptr, hcl_oow_t len) static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len)
{ {
while (len > 0) while (len > 0)
{ {
@ -117,6 +126,70 @@ static int write_all (int fd, const char* ptr, hcl_oow_t len)
return 0; return 0;
} }
static int write_log (hcl_server_t* server, const hcl_bch_t* ptr, hcl_oow_t len)
{
server_xtn_t* xtn;
xtn = hcl_server_getxtn(server);
while (len > 0)
{
if (xtn->logbuf.len > 0)
{
hcl_oow_t rcapa, cplen;
rcapa = HCL_COUNTOF(xtn->logbuf.buf) - xtn->logbuf.len;
cplen = (len >= rcapa)? rcapa: len;
memcpy (&xtn->logbuf.buf[xtn->logbuf.len], ptr, cplen);
xtn->logbuf.len += cplen;
ptr += cplen;
len -= cplen;
if (xtn->logbuf.len >= HCL_COUNTOF(xtn->logbuf.buf))
{
write_all(xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len);
xtn->logbuf.len = 0;
}
}
else
{
hcl_oow_t rcapa;
rcapa = HCL_COUNTOF(xtn->logbuf.buf);
if (len >= rcapa)
{
write_all (xtn->logfd, ptr, rcapa);
ptr += rcapa;
len -= rcapa;
}
else
{
memcpy (xtn->logbuf.buf, ptr, len);
xtn->logbuf.len += len;
ptr += len;
len -= len;
}
}
}
return 0;
}
static void flush_log (hcl_server_t* server)
{
server_xtn_t* xtn;
xtn = hcl_server_getxtn(server);
if (xtn->logbuf.len > 0)
{
write_all (xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len);
xtn->logbuf.len = 0;
}
}
static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len) static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
{ {
hcl_bch_t buf[256]; hcl_bch_t buf[256];
@ -154,7 +227,6 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c
size_t tslen; size_t tslen;
struct tm tm, *tmp; struct tm tm, *tmp;
now = time(NULL); now = time(NULL);
tmp = localtime_r (&now, &tm); tmp = localtime_r (&now, &tm);
@ -170,21 +242,21 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c
} }
/* TODO: less write system calls by having a buffer */ /* TODO: less write system calls by having a buffer */
write_all (logfd, ts, tslen); write_log (server, ts, tslen);
if (wid != HCL_SERVER_WID_INVALID) if (wid != HCL_SERVER_WID_INVALID)
{ {
/* TODO: check if the underlying snprintf support %zd */ /* TODO: check if the underlying snprintf support %zd */
tslen = snprintf (ts, sizeof(ts), "[%zu] ", wid); tslen = snprintf (ts, sizeof(ts), "[%zu] ", wid);
write_all (logfd, ts, tslen); write_log (server, ts, tslen);
} }
} }
if (xtn->logfd_istty) if (xtn->logfd_istty)
{ {
if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); if (mask & HCL_LOG_FATAL) write_log (server, "\x1B[1;31m", 7);
else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); else if (mask & HCL_LOG_ERROR) write_log (server, "\x1B[1;32m", 7);
else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); else if (mask & HCL_LOG_WARN) write_log (server, "\x1B[1;33m", 7);
} }
#if defined(HCL_OOCH_IS_UCH) #if defined(HCL_OOCH_IS_UCH)
@ -207,7 +279,7 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c
/*assert (ucslen > 0);*/ /*assert (ucslen > 0);*/
/* attempt to write all converted characters */ /* attempt to write all converted characters */
if (write_all(logfd, buf, bcslen) <= -1) break; if (write_log(server, buf, bcslen) <= -1) break;
if (n == 0) break; if (n == 0) break;
else else
@ -223,13 +295,15 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c
} }
} }
#else #else
write_all (logfd, msg, len); write_log (server, msg, len);
#endif #endif
if (xtn->logfd_istty) if (xtn->logfd_istty)
{ {
if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_log (server, "\x1B[0m", 4);
} }
flush_log (server);
} }
/* ========================================================================= */ /* ========================================================================= */