undergoing code refactoring of xproto, server, client code
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
hyung-hwan 2024-04-21 22:15:04 +09:00
parent 6eee6bc9eb
commit 7e782809f9
9 changed files with 2979 additions and 426 deletions

View File

@ -69,9 +69,6 @@ struct client_xtn_t
hcl_bch_t buf[4096];
hcl_oow_t len;
} logbuf;
int reply_count;
hcl_oow_t data_length;
};
/* ========================================================================= */
@ -491,133 +488,19 @@ static int send_iov (int sck, struct iovec* iov, int count)
/* ========================================================================= */
enum hcl_xproto_rcv_state_t
struct proto_xtn_t
{
HCL_XPROTO_RCV_HDR,
HCL_XPROTO_RCV_PLD,
int x;
};
typedef enum hcl_xproto_rcv_state_t hcl_xproto_rcv_state_t;
typedef struct proto_xtn_t proto_xtn_t;
struct hcl_xproto_t
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
{
hcl_t* hcl;
struct
if (type == HCL_XPKT_STDOUT)
{
hcl_xproto_rcv_state_t state;
hcl_oow_t len_needed;
unsigned int eof: 1;
hcl_oow_t len;
hcl_uint8_t buf[4096];
hcl_xpkt_hdr_t hdr;
} rcv;
};
typedef struct hcl_xproto_t hcl_xproto_t;
static int receive_raw_bytes (hcl_xproto_t* proto, int sck, hcl_ntime_t* idle_tmout)
{
hcl_t* hcl = proto->hcl;
struct pollfd pfd;
int tmout, actual_tmout;
ssize_t x;
int n;
if (HCL_UNLIKELY(proto->rcv.eof))
{
hcl_seterrbfmt (hcl, HCL_EGENERIC, "connection closed");
return -1;
/*if (len > 0) fwrite (data, 1, len, stdout); */
if (len > 0) fprintf (stdout, "%.*s", (int)len, data);
}
tmout = idle_tmout? HCL_SECNSEC_TO_MSEC(idle_tmout->sec, idle_tmout->nsec): -1;
actual_tmout = (tmout <= 0)? 10000: tmout;
pfd.fd = sck;
pfd.events = POLLIN | POLLERR;
pfd.revents = 0;
n = poll(&pfd, 1, actual_tmout);
if (n <= -1)
{
if (errno == EINTR) return 0;
hcl_seterrwithsyserr (hcl, 0, errno);
return -1;
}
else if (n == 0)
{
/* timed out - no activity on the pfd */
if (tmout > 0)
{
/* timeout explicity set. no activity for that duration. considered idle */
hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the socket %d", sck);
return -1;
}
return 0; /* didn't read yet */
}
if (pfd.revents & POLLERR)
{
hcl_seterrbfmt (hcl, HCL_EGENERIC, "error condition detected on socket %d", sck);
return -1;
}
x = recv(sck, &proto->rcv.buf[proto->rcv.len], HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len, 0);
if (x <= -1)
{
if (errno == EINTR) return 0; /* didn't read read */
hcl_seterrwithsyserr (hcl, 0, errno);
return -1;
}
if (x == 0) proto->rcv.eof = 1;
proto->rcv.len += x;
//printf ("RECEIVED %d rcv.len %d rcv.len_needed %d [%.*s]\n", (int)x, (int)proto->rcv.len, (int)proto->rcv.len_needed, (int)proto->rcv.len, proto->rcv.buf);
return 1; /* read some data */
}
static int handle_received_data (hcl_xproto_t* proto)
{
//printf ("HANDLE RECIVED rcv.len %d rcv.len_needed %d [%.*s]\n", (int)proto->rcv.len, (int)proto->rcv.len_needed, (int)proto->rcv.len, proto->rcv.buf);
switch (proto->rcv.state)
{
case HCL_XPROTO_RCV_HDR:
if (proto->rcv.len < HCL_SIZEOF(proto->rcv.hdr)) return 0; /* need more data */
memcpy (&proto->rcv.hdr, proto->rcv.buf, HCL_SIZEOF(proto->rcv.hdr));
//proto->rcv.hdr.len = hcl_ntoh16(proto->rcv.hdr.len); /* keep this in the host byte order */
/* consume the header */
memmove (proto->rcv.buf, &proto->rcv.buf[HCL_SIZEOF(proto->rcv.hdr)], proto->rcv.len - HCL_SIZEOF(proto->rcv.hdr));
proto->rcv.len -= HCL_SIZEOF(proto->rcv.hdr);
/* switch to the payload mode */
proto->rcv.state = HCL_XPROTO_RCV_PLD;
proto->rcv.len_needed = proto->rcv.hdr.len;
return 0;
case HCL_XPROTO_RCV_PLD:
if (proto->rcv.len < proto->rcv.hdr.len) return 0; /* need more payload data */
if (proto->rcv.hdr.type == HCL_XPKT_STDOUT)
{
if (proto->rcv.hdr.len > 0)
fprintf (stdout, "%.*s", (int)proto->rcv.hdr.len, proto->rcv.buf);
}
if (proto->rcv.hdr.len > 0)
{
memmove (proto->rcv.buf, &proto->rcv.buf[proto->rcv.hdr.len], proto->rcv.len - proto->rcv.hdr.len);
proto->rcv.len -= proto->rcv.hdr.len;
}
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
break;
}
return 1;
}
@ -634,11 +517,11 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char*
ssize_t n;
const char* scptr;
const char* sccur;
hcl_xproto_t proto_buf;
hcl_xproto_t* proto = &proto_buf;
hcl_xproto_t* proto = HCL_NULL;
client_xtn_t* client_xtn;
proto_xtn_t* proto_xtn;
hcl_xproto_cb_t proto_cb;
client_xtn = hcl_client_getxtn(client);
@ -684,14 +567,17 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char*
goto oops;
}
/* TODO: create hcl_xproto_open... */
memset (proto, 0, HCL_SIZEOF(*proto));
proto->hcl = hcl_openstdwithmmgr(hcl_client_getmmgr(client), 0, HCL_NULL); // TODO:
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_SIZEOF(proto->rcv.hdr);
proto->rcv.eof = 0;
// TODO: destroy xproto and data upon termination.
memset (&proto, 0, HCL_SIZEOF(proto_cb));
proto_cb.on_packet = handle_packet;
proto = hcl_xproto_open(hcl_client_getmmgr(client), &proto_cb, HCL_SIZEOF(*proto_xtn));
if (HCL_UNLIKELY(!proto))
{
fprintf (stderr, "cannot open protocol to %s\n", ipaddr);
goto oops;
}
proto_xtn = hcl_xproto_getxtn(proto);
//proto_xtn->client = client;
scptr = sccur = script;
while (1)
@ -774,27 +660,44 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char*
if (pfd.revents & POLLIN)
{
//printf ("receiving...\n");
if (receive_raw_bytes(proto, sck, HCL_NULL) <= -1) break;
hcl_oow_t bcap;
hcl_uint8_t* bptr;
bptr = hcl_xproto_getbuf(proto, &bcap);;
x = recv(sck, bptr, bcap, 0);
if (x <= -1)
{
if (errno == EINTR) goto carry_on; /* didn't read read */
/*hcl_seterrwithsyserr (hcl, 0, errno); */
/* TODO: error info set... */
return -1;
}
if (x == 0) hcl_xproto_seteof(proto, 1);
hcl_xproto_advbuf (proto, x);
}
while (/*proto->rcv.len > 0 &&*/ proto->rcv.len >= proto->rcv.len_needed)
carry_on:
while (hcl_xproto_ready(proto))
{
if (handle_received_data(proto) <= -1)
if ((n = hcl_xproto_process(proto)) <= -1)
{
goto oops;
/* TODO: proper error message */
return -1;
}
if (n == 0)
{
/* TODO: chceck if there is remaining data in the buffer...?? */
printf ("NO MORE DATA. EXITING...\n");
goto done;
}
}
}
client_xtn->data_length = 0;
client_xtn->reply_count = 0;
if (hcl_xproto_geteof(proto)) break;
}
done:
/* TODO: we can check if the buffer has all been consumed. if not, there is trailing garbage.. */
/*shutdown (sck, (shut_wr_after_req? SHUT_RD: SHUT_RDWR));*/
if (!shut_wr_after_req) shutdown (sck, SHUT_RDWR);
/*{
struct linger linger;
linger.l_onoff = 1;
@ -802,10 +705,12 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char*
setsockopt (sck, SOL_SOCKET, SO_LINGER, (char *) &linger, sizeof(linger));
}*/
hcl_xproto_close (proto);
close (sck);
return 0;
oops:
if (proto) hcl_xproto_close (proto);
if (sck >= 0) close (sck);
return -1;
}

View File

@ -106,14 +106,15 @@ endif
if ENABLE_HCLX
pkglib_LTLIBRARIES += libhclx.la
pkginclude_HEADERS += hcl-c.h hcl-s.h hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
pkginclude_HEADERS += hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
libhclx_la_SOURCES = \
tmr.c hcl-tmr.h \
xutl.c xutl-sa.h hcl-xutl.h \
json.c hcl-json.h \
hcl-s.c hcl-s.h \
hcl-x.c hcl-x.h \
hcl-c.c hcl-c.h
hcl-x.h \
x-client.c \
x-proto.c \
x-server.c
libhclx_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) $(CPPFLAGS_PFMOD)
libhclx_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhclx_la_LIBADD = libhcl.la $(LIBADD_LIB_COMMON)

View File

@ -97,7 +97,7 @@ host_triplet = @host@
@ENABLE_STATIC_MODULE_TRUE@ ../mod/libhcl-str.la \
@ENABLE_STATIC_MODULE_TRUE@ ../mod/libhcl-sys.la
@ENABLE_HCLX_TRUE@am__append_7 = libhclx.la
@ENABLE_HCLX_TRUE@am__append_8 = hcl-c.h hcl-s.h hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
@ENABLE_HCLX_TRUE@am__append_8 = hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
@ -171,12 +171,12 @@ libhcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@ENABLE_HCLX_TRUE@libhclx_la_DEPENDENCIES = libhcl.la \
@ENABLE_HCLX_TRUE@ $(am__DEPENDENCIES_5)
am__libhclx_la_SOURCES_DIST = tmr.c hcl-tmr.h xutl.c xutl-sa.h \
hcl-xutl.h json.c hcl-json.h hcl-s.c hcl-s.h hcl-x.c hcl-x.h \
hcl-c.c hcl-c.h
hcl-xutl.h json.c hcl-json.h hcl-x.h x-client.c x-proto.c \
x-server.c
@ENABLE_HCLX_TRUE@am_libhclx_la_OBJECTS = libhclx_la-tmr.lo \
@ENABLE_HCLX_TRUE@ libhclx_la-xutl.lo libhclx_la-json.lo \
@ENABLE_HCLX_TRUE@ libhclx_la-hcl-s.lo libhclx_la-hcl-x.lo \
@ENABLE_HCLX_TRUE@ libhclx_la-hcl-c.lo
@ENABLE_HCLX_TRUE@ libhclx_la-x-client.lo libhclx_la-x-proto.lo \
@ENABLE_HCLX_TRUE@ libhclx_la-x-server.lo
libhclx_la_OBJECTS = $(am_libhclx_la_OBJECTS)
libhclx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -211,10 +211,11 @@ am__depfiles_remade = ./$(DEPDIR)/libhcl_la-bigint.Plo \
./$(DEPDIR)/libhcl_la-std.Plo ./$(DEPDIR)/libhcl_la-sym.Plo \
./$(DEPDIR)/libhcl_la-utf16.Plo ./$(DEPDIR)/libhcl_la-utf8.Plo \
./$(DEPDIR)/libhcl_la-utl.Plo ./$(DEPDIR)/libhcl_la-xchg.Plo \
./$(DEPDIR)/libhcl_la-xma.Plo ./$(DEPDIR)/libhclx_la-hcl-c.Plo \
./$(DEPDIR)/libhclx_la-hcl-s.Plo \
./$(DEPDIR)/libhclx_la-hcl-x.Plo \
./$(DEPDIR)/libhclx_la-json.Plo ./$(DEPDIR)/libhclx_la-tmr.Plo \
./$(DEPDIR)/libhcl_la-xma.Plo ./$(DEPDIR)/libhclx_la-json.Plo \
./$(DEPDIR)/libhclx_la-tmr.Plo \
./$(DEPDIR)/libhclx_la-x-client.Plo \
./$(DEPDIR)/libhclx_la-x-proto.Plo \
./$(DEPDIR)/libhclx_la-x-server.Plo \
./$(DEPDIR)/libhclx_la-xutl.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@ -244,7 +245,7 @@ am__can_run_installinfo = \
esac
am__pkginclude_HEADERS_DIST = hcl.h hcl-chr.h hcl-cmn.h hcl-fmt.h \
hcl-opt.h hcl-pac1.h hcl-rbt.h hcl-upac.h hcl-utl.h hcl-xma.h \
hcl-c.h hcl-s.h hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
hcl-x.h hcl-tmr.h hcl-xutl.h hcl-json.h
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
hcl-cfg.h.in
@ -479,9 +480,10 @@ libhcl_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_6)
@ENABLE_HCLX_TRUE@ tmr.c hcl-tmr.h \
@ENABLE_HCLX_TRUE@ xutl.c xutl-sa.h hcl-xutl.h \
@ENABLE_HCLX_TRUE@ json.c hcl-json.h \
@ENABLE_HCLX_TRUE@ hcl-s.c hcl-s.h \
@ENABLE_HCLX_TRUE@ hcl-x.c hcl-x.h \
@ENABLE_HCLX_TRUE@ hcl-c.c hcl-c.h
@ENABLE_HCLX_TRUE@ hcl-x.h \
@ENABLE_HCLX_TRUE@ x-client.c \
@ENABLE_HCLX_TRUE@ x-proto.c \
@ENABLE_HCLX_TRUE@ x-server.c
@ENABLE_HCLX_TRUE@libhclx_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON) $(CPPFLAGS_PFMOD)
@ENABLE_HCLX_TRUE@libhclx_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
@ -611,11 +613,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-xchg.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-xma.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-hcl-c.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-hcl-s.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-hcl-x.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-json.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-tmr.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-x-client.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-x-proto.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-x-server.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhclx_la-xutl.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@ -865,26 +867,26 @@ libhclx_la-json.lo: json.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-json.lo `test -f 'json.c' || echo '$(srcdir)/'`json.c
libhclx_la-hcl-s.lo: hcl-s.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-hcl-s.lo -MD -MP -MF $(DEPDIR)/libhclx_la-hcl-s.Tpo -c -o libhclx_la-hcl-s.lo `test -f 'hcl-s.c' || echo '$(srcdir)/'`hcl-s.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-hcl-s.Tpo $(DEPDIR)/libhclx_la-hcl-s.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hcl-s.c' object='libhclx_la-hcl-s.lo' libtool=yes @AMDEPBACKSLASH@
libhclx_la-x-client.lo: x-client.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-x-client.lo -MD -MP -MF $(DEPDIR)/libhclx_la-x-client.Tpo -c -o libhclx_la-x-client.lo `test -f 'x-client.c' || echo '$(srcdir)/'`x-client.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-x-client.Tpo $(DEPDIR)/libhclx_la-x-client.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x-client.c' object='libhclx_la-x-client.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-hcl-s.lo `test -f 'hcl-s.c' || echo '$(srcdir)/'`hcl-s.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-x-client.lo `test -f 'x-client.c' || echo '$(srcdir)/'`x-client.c
libhclx_la-hcl-x.lo: hcl-x.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-hcl-x.lo -MD -MP -MF $(DEPDIR)/libhclx_la-hcl-x.Tpo -c -o libhclx_la-hcl-x.lo `test -f 'hcl-x.c' || echo '$(srcdir)/'`hcl-x.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-hcl-x.Tpo $(DEPDIR)/libhclx_la-hcl-x.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hcl-x.c' object='libhclx_la-hcl-x.lo' libtool=yes @AMDEPBACKSLASH@
libhclx_la-x-proto.lo: x-proto.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-x-proto.lo -MD -MP -MF $(DEPDIR)/libhclx_la-x-proto.Tpo -c -o libhclx_la-x-proto.lo `test -f 'x-proto.c' || echo '$(srcdir)/'`x-proto.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-x-proto.Tpo $(DEPDIR)/libhclx_la-x-proto.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x-proto.c' object='libhclx_la-x-proto.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-hcl-x.lo `test -f 'hcl-x.c' || echo '$(srcdir)/'`hcl-x.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-x-proto.lo `test -f 'x-proto.c' || echo '$(srcdir)/'`x-proto.c
libhclx_la-hcl-c.lo: hcl-c.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-hcl-c.lo -MD -MP -MF $(DEPDIR)/libhclx_la-hcl-c.Tpo -c -o libhclx_la-hcl-c.lo `test -f 'hcl-c.c' || echo '$(srcdir)/'`hcl-c.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-hcl-c.Tpo $(DEPDIR)/libhclx_la-hcl-c.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hcl-c.c' object='libhclx_la-hcl-c.lo' libtool=yes @AMDEPBACKSLASH@
libhclx_la-x-server.lo: x-server.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhclx_la-x-server.lo -MD -MP -MF $(DEPDIR)/libhclx_la-x-server.Tpo -c -o libhclx_la-x-server.lo `test -f 'x-server.c' || echo '$(srcdir)/'`x-server.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhclx_la-x-server.Tpo $(DEPDIR)/libhclx_la-x-server.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x-server.c' object='libhclx_la-x-server.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-hcl-c.lo `test -f 'hcl-c.c' || echo '$(srcdir)/'`hcl-c.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) $(libhclx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhclx_la-x-server.lo `test -f 'x-server.c' || echo '$(srcdir)/'`x-server.c
mostlyclean-libtool:
-rm -f *.lo
@ -1068,11 +1070,11 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libhcl_la-utl.Plo
-rm -f ./$(DEPDIR)/libhcl_la-xchg.Plo
-rm -f ./$(DEPDIR)/libhcl_la-xma.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-c.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-s.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-x.Plo
-rm -f ./$(DEPDIR)/libhclx_la-json.Plo
-rm -f ./$(DEPDIR)/libhclx_la-tmr.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-client.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-proto.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-server.Plo
-rm -f ./$(DEPDIR)/libhclx_la-xutl.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
@ -1148,11 +1150,11 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libhcl_la-utl.Plo
-rm -f ./$(DEPDIR)/libhcl_la-xchg.Plo
-rm -f ./$(DEPDIR)/libhcl_la-xma.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-c.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-s.Plo
-rm -f ./$(DEPDIR)/libhclx_la-hcl-x.Plo
-rm -f ./$(DEPDIR)/libhclx_la-json.Plo
-rm -f ./$(DEPDIR)/libhclx_la-tmr.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-client.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-proto.Plo
-rm -f ./$(DEPDIR)/libhclx_la-x-server.Plo
-rm -f ./$(DEPDIR)/libhclx_la-xutl.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

View File

@ -110,45 +110,6 @@ typedef struct server_hcl_xtn_t server_hcl_xtn_t;
/* ---------------------------------- */
enum hcl_xproto_rcv_state_t
{
HCL_XPROTO_RCV_HDR,
HCL_XPROTO_RCV_PLD
};
typedef enum hcl_xproto_rcv_state_t hcl_xproto_rcv_state_t;
struct hcl_xproto_t
{
hcl_oow_t _instsize;
hcl_mmgr_t* _mmgr;
hcl_tmr_index_t exec_runtime_event_index;
struct
{
hcl_xproto_rcv_state_t state;
hcl_oow_t len_needed;
unsigned int eof: 1;
hcl_oow_t len;
hcl_uint8_t buf[HCL_XPKT_MAX_PLD_LEN];
/* normalize header of hcl_xpkt_hdr_t with combined bits into separate placeholders */
struct
{
hcl_uint8_t id;
hcl_uint8_t type;
hcl_uint16_t len; /* this is wider than the len field of hcl_xpkt_hdr_t */
} hdr;
} rcv;
struct
{
} snd;
};
/* ---------------------------------- */
enum hcl_server_worker_state_t
{
HCL_SERVER_WORKER_STATE_DEAD = 0,
@ -181,6 +142,7 @@ struct hcl_server_worker_t
hcl_ntime_t alloc_time;
hcl_server_worker_state_t state;
hcl_server_worker_opstate_t opstate;
hcl_tmr_index_t exec_runtime_event_index;
hcl_xproto_t* proto;
hcl_t* hcl;
@ -694,6 +656,16 @@ static void fini_hcl (hcl_t* hcl)
*/
/* ========================================================================= */
static hcl_server_worker_t* proto_to_worker (hcl_xproto_t* proto)
{
proto_xtn_t* prtxtn;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
return prtxtn->worker;
}
/* ========================================================================= */
#define SERVER_LOGMASK_INFO (HCL_LOG_INFO | HCL_LOG_APP)
#define SERVER_LOGMASK_ERROR (HCL_LOG_ERROR | HCL_LOG_APP)
@ -728,15 +700,9 @@ static void exec_runtime_handler (hcl_tmr_t* tmr, const hcl_ntime_t* now, hcl_tm
{
/* [NOTE] this handler is executed in the main server thread
* when it calls hcl_tmr_fire(). */
hcl_xproto_t* proto;
hcl_server_worker_t* worker;
proto_xtn_t* prtxtn;
proto = (hcl_xproto_t*)evt->ctx;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker((hcl_xproto_t*)evt->ctx);
/* TODO: can we use worker->hcl for logging before abort?? */
HCL_LOG1 (worker->server->dummy_hcl, SERVER_LOGMASK_INFO, "Aborting script execution for max_actor_runtime exceeded [%zu]\n", worker->wid);
hcl_abort (worker->hcl);
@ -746,19 +712,16 @@ static void exec_runtime_updater (hcl_tmr_t* tmr, hcl_tmr_index_t old_index, hcl
{
/* [NOTE] this handler is executed in the main server thread
* when it calls hcl_tmr_fire() */
hcl_xproto_t* proto;
hcl_server_worker_t* worker;
proto_xtn_t* prtxtn;
proto = (hcl_xproto_t*)evt->ctx;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
HCL_ASSERT (worker->hcl, proto->exec_runtime_event_index == old_index);
worker = proto_to_worker(proto);
HCL_ASSERT (worker->hcl, worker->exec_runtime_event_index == old_index);
/* the event is being removed by hcl_tmr_fire() or by hcl_tmr_delete()
* if new_index is HCL_TMR_INVALID_INDEX. it's being updated if not. */
proto->exec_runtime_event_index = new_index;
worker->exec_runtime_event_index = new_index;
}
static int insert_exec_timer (hcl_xproto_t* proto, const hcl_ntime_t* tmout)
@ -767,15 +730,13 @@ static int insert_exec_timer (hcl_xproto_t* proto, const hcl_ntime_t* tmout)
hcl_tmr_event_t event;
hcl_tmr_index_t index;
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_server_t* server;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
server = worker->server;
HCL_ASSERT (worker->hcl, proto->exec_runtime_event_index == HCL_TMR_INVALID_INDEX);
HCL_ASSERT (worker->hcl, worker->exec_runtime_event_index == HCL_TMR_INVALID_INDEX);
HCL_MEMSET (&event, 0, HCL_SIZEOF(event));
event.ctx = proto;
@ -786,7 +747,7 @@ static int insert_exec_timer (hcl_xproto_t* proto, const hcl_ntime_t* tmout)
pthread_mutex_lock (&server->tmr_mutex);
index = hcl_tmr_insert(server->tmr, &event);
proto->exec_runtime_event_index = index;
worker->exec_runtime_event_index = index;
if (index != HCL_TMR_INVALID_INDEX)
{
/* inform the server of timer event change */
@ -800,25 +761,23 @@ static int insert_exec_timer (hcl_xproto_t* proto, const hcl_ntime_t* tmout)
static void delete_exec_timer (hcl_xproto_t* proto)
{
/* [NOTE] this is executed in the worker thread. if the event has been fired
* in the server thread, proto->exec_runtime_event_index should be
* in the server thread, worker->exec_runtime_event_index should be
* HCL_TMR_INVALID_INDEX as set by exec_runtime_handler */
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_server_t* server;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
server = worker->server;
pthread_mutex_lock (&server->tmr_mutex);
if (proto->exec_runtime_event_index != HCL_TMR_INVALID_INDEX)
if (worker->exec_runtime_event_index != HCL_TMR_INVALID_INDEX)
{
/* the event has not been fired yet. let's delete it
* if it has been fired, the index it shall be HCL_TMR_INVALID_INDEX already */
hcl_tmr_delete (server->tmr, proto->exec_runtime_event_index);
HCL_ASSERT (worker->hcl, proto->exec_runtime_event_index == HCL_TMR_INVALID_INDEX);
/*proto->exec_runtime_event_index = HCL_TMR_INVALID_INDEX; */
hcl_tmr_delete (server->tmr, worker->exec_runtime_event_index);
HCL_ASSERT (worker->hcl, worker->exec_runtime_event_index == HCL_TMR_INVALID_INDEX);
/*worker->exec_runtime_event_index = HCL_TMR_INVALID_INDEX; */
}
pthread_mutex_unlock (&server->tmr_mutex);
}
@ -827,12 +786,10 @@ static int execute_script (hcl_xproto_t* proto, const hcl_bch_t* trigger)
{
hcl_oop_t obj;
const hcl_ooch_t* failmsg = HCL_NULL;
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_server_t* server;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
server = worker->server;
#if 0
@ -905,24 +862,18 @@ static void reformat_synerr (hcl_t* hcl)
static void send_proto_hcl_error (hcl_xproto_t* proto)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
if (HCL_ERRNUM(worker->hcl) == HCL_ESYNERR) reformat_synerr (worker->hcl);
send_error_message (proto, hcl_geterrmsg(worker->hcl));
}
static void show_server_workers (hcl_xproto_t* proto)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker, * w;
hcl_server_t* server;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
server = worker->server;
pthread_mutex_lock (&server->worker_mutex);
@ -936,13 +887,11 @@ static void show_server_workers (hcl_xproto_t* proto)
static int kill_server_worker (hcl_xproto_t* proto, hcl_oow_t wid)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_server_t* server;
int xret = 0;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
server = worker->server;
pthread_mutex_lock (&server->worker_mutex);
@ -979,14 +928,12 @@ static int kill_server_worker (hcl_xproto_t* proto, hcl_oow_t wid)
return xret;
}
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, void* data, hcl_oow_t len)
static int handle_packet (hcl_xproto_t* proto, hcl_xpkt_type_t type, const void* data, hcl_oow_t len)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_t* hcl;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
hcl = worker->hcl;
printf ("HANDLE PACKET TYPE => %d\n", type);
@ -1082,15 +1029,13 @@ static int send_iov (int sck, struct iovec* iov, int count)
static int send_stdout_bytes (hcl_xproto_t* proto, const hcl_bch_t* data, hcl_oow_t len)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
hcl_xpkt_hdr_t hdr;
struct iovec iov[2];
const hcl_bch_t* ptr, * cur, * end;
hcl_uint16_t seglen;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
ptr = cur = data;
end = data + len;
@ -1126,15 +1071,13 @@ printf ("SENDING BYTES [%.*s]\n", (int)len, data);
#if defined(HCL_OOCH_IS_UCH)
static int send_stdout_chars (hcl_xproto_t* proto, const hcl_ooch_t* data, hcl_oow_t len)
{
proto_xtn_t* prtxtn;
hcl_server_worker_t* worker;
const hcl_ooch_t* ptr, * end;
hcl_bch_t tmp[256];
hcl_oow_t tln, pln;
int n;
prtxtn = (proto_xtn_t*)hcl_xproto_getxtn(proto);
worker = prtxtn->worker;
worker = proto_to_worker(proto);
ptr = data;
end = data + len;
@ -1155,139 +1098,6 @@ static int send_stdout_chars (hcl_xproto_t* proto, const hcl_ooch_t* data, hcl_o
}
#endif
/* ========================================================================= */
hcl_xproto_t* hcl_xproto_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize)
{
hcl_xproto_t* proto;
proto = (hcl_xproto_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*proto) + xtnsize);
if (HCL_UNLIKELY(!proto)) return HCL_NULL;
HCL_MEMSET (proto, 0, HCL_SIZEOF(*proto));
proto->_instsize = HCL_SIZEOF(*proto);
proto->_mmgr = mmgr;
proto->exec_runtime_event_index = HCL_TMR_INVALID_INDEX;
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_XPKT_HDR_LEN;
proto->rcv.eof = 0;
return proto;
}
void hcl_xproto_close (hcl_xproto_t* proto)
{
HCL_MMGR_FREE (proto->_mmgr, proto);
}
void* hcl_xproto_getxtn (hcl_xproto_t* proto)
{
return (proto + 1);
}
int hcl_xprpto_feed (hcl_xproto_t* proto, const void* data, hcl_oow_t len)
{
}
hcl_uint8_t* hcl_xproto_getbuf (hcl_xproto_t* proto, hcl_oow_t* capa)
{
*capa = HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len;
return &proto->rcv.buf[proto->rcv.len];
}
void hcl_xproto_seteof (hcl_xproto_t* proto, int v)
{
proto->rcv.eof = v;
}
void hcl_xproto_advbuf (hcl_xproto_t* proto, hcl_oow_t inc)
{
proto->rcv.len += inc;
}
int hcl_xproto_ready (hcl_xproto_t* proto)
{
/* has it received suffient data for processing? */
return proto->rcv.len >= proto->rcv.len_needed;
}
int hcl_xproto_process (hcl_xproto_t* proto)
{
int n;
hcl_xpkt_hdr_t* hdr;
switch (proto->rcv.state)
{
case HCL_XPROTO_RCV_HDR:
if (proto->rcv.len < HCL_XPKT_HDR_LEN) goto carry_on; /* need more data */
hdr = (hcl_xpkt_hdr_t*)proto->rcv.buf;
proto->rcv.hdr.id = hdr->id;
proto->rcv.hdr.type = hdr->type & 0x0F;
proto->rcv.hdr.len = (hcl_uint16_t)hdr->len | ((hcl_uint16_t)(hdr->type >> 4) << 8);
/* consume the header */
HCL_MEMMOVE (proto->rcv.buf, &proto->rcv.buf[HCL_XPKT_HDR_LEN], proto->rcv.len - HCL_XPKT_HDR_LEN);
proto->rcv.len -= HCL_XPKT_HDR_LEN;
/* switch to the payload mode */
if (proto->rcv.hdr.len > 0)
{
proto->rcv.state = HCL_XPROTO_RCV_PLD;
proto->rcv.len_needed = proto->rcv.hdr.len;
}
else
{
/* take shortcut */
/* TODO: convert handle_packet as call back */
n = handle_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
if (n <= -1) goto fail_with_errmsg;
if (n == 0) return 0;
}
break;
case HCL_XPROTO_RCV_PLD:
if (proto->rcv.len < proto->rcv.hdr.len) goto carry_on; /* need more payload data */
/* TODO: convert handle_packet as call back */
n = handle_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
/* TODO: minimize the use of HCL_MEMOVE... use the buffer */
/* switch to the header mode */
if (proto->rcv.hdr.len > 0)
{
HCL_MEMMOVE (proto->rcv.buf, &proto->rcv.buf[proto->rcv.hdr.len], proto->rcv.len - proto->rcv.hdr.len);
proto->rcv.len -= proto->rcv.hdr.len;
}
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_XPKT_HDR_LEN;
if (n <= -1) goto fail_with_errmsg;
if (n == 0) return 0;
break;
default:
/*
hcl_seterrbfmt (hcl, HCL_EINTERN, "invalid request state %d", (int)proto->rcv.state);
*/
/* TODO: call back */
goto fail_with_errmsg;
}
carry_on:
return 1;
fail_with_errmsg:
// TODO: proper error handling
//send_proto_hcl_error (proto);
//HCL_LOG1 (hcl, SERVER_LOGMASK_ERROR, "Unable to compile .SCRIPT contents - %js\n", hcl_geterrmsg(worker->hcl));
return -1;
}
/* ========================================================================= */
hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_prim_t* prim, hcl_errnum_t* errnum)
@ -1520,6 +1330,7 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck, con
worker->sck = cli_sck;
worker->peeraddr = *peeraddr;
worker->server = server;
worker->exec_runtime_event_index = HCL_TMR_INVALID_INDEX;
server->dummy_hcl->vmprim.vm_gettime (server->dummy_hcl, &worker->alloc_time); /* TODO: the callback may return monotonic time. find a way to guarantee it is realtime??? */
@ -1680,7 +1491,6 @@ static int worker_step (hcl_server_worker_t* worker)
if (x <= -1)
{
if (errno == EINTR) goto carry_on; /* didn't read read */
hcl_seterrwithsyserr (hcl, 0, errno);
return -1;
}
@ -1779,8 +1589,12 @@ static int init_worker_proto (hcl_server_worker_t* worker)
{
hcl_xproto_t* proto;
proto_xtn_t* xtn;
hcl_xproto_cb_t cb;
proto = hcl_xproto_open(hcl_server_getmmgr(worker->server), HCL_SIZEOF(*xtn));
HCL_MEMSET (&cb, 0, HCL_SIZEOF(cb));
cb.on_packet = handle_packet;
proto = hcl_xproto_open(hcl_server_getmmgr(worker->server), &cb, HCL_SIZEOF(*xtn));
if (HCL_UNLIKELY(!proto)) return -1;
xtn = hcl_xproto_getxtn(proto);
@ -2754,6 +2568,3 @@ void hcl_client_freemem (hcl_client_t* client, void* ptr)
{
HCL_MMGR_FREE (client->_mmgr, ptr);
}

View File

@ -70,6 +70,19 @@ typedef struct hcl_xpkt_hdr_t hcl_xpkt_hdr_t;
typedef struct hcl_xproto_t hcl_xproto_t;
typedef int (*hcl_xproto_cb_on_packet) (
hcl_xproto_t* proto,
hcl_xpkt_type_t type,
const void* data,
hcl_oow_t len
);
struct hcl_xproto_cb_t
{
hcl_xproto_cb_on_packet on_packet;
};
typedef struct hcl_xproto_cb_t hcl_xproto_cb_t;
/* ---------------------------------------------------------------------- */
typedef struct hcl_server_proto_t hcl_server_proto_t;
@ -400,8 +413,9 @@ HCL_EXPORT void hcl_client_freemem (
/* ---------------------------------------------------------------------- */
HCL_EXPORT hcl_xproto_t* hcl_xproto_open (
hcl_mmgr_t* mmgr,
hcl_oow_t xtnsize
hcl_mmgr_t* mmgr,
hcl_xproto_cb_t* cb,
hcl_oow_t xtnsize
);
HCL_EXPORT void hcl_xproto_close (
@ -417,6 +431,10 @@ hcl_uint8_t* hcl_xproto_getbuf (
hcl_oow_t* capa
);
int hcl_xproto_geteof (
hcl_xproto_t* proto
);
void hcl_xproto_seteof (
hcl_xproto_t* proto,
int v

View File

@ -110,17 +110,17 @@ HCL_EXPORT int hcl_bcharstosckaddr (
);
#if defined(HCL_HAVE_INLINE)
static HCL_INLINE int hcl_uchars_to_sckaddr (const hcl_uch_t* str, hcl_oow_t len, hcl_sckaddr_t* sckaddr, hcl_scklen_t* scklen)
{
return hcl_ucharstosckaddr(HCL_NULL, str, len, sckaddr, scklen);
}
static HCL_INLINE int hcl_bchars_to_sckaddr (const hcl_bch_t* str, hcl_oow_t len, hcl_sckaddr_t* sckaddr, hcl_scklen_t* scklen)
{
return hcl_bcharstosckaddr(HCL_NULL, str, len, sckaddr, scklen);
}
static HCL_INLINE int hcl_uchars_to_sckaddr (const hcl_uch_t* str, hcl_oow_t len, hcl_sckaddr_t* sckaddr, hcl_scklen_t* scklen)
{
return hcl_ucharstosckaddr(HCL_NULL, str, len, sckaddr, scklen);
}
static HCL_INLINE int hcl_bchars_to_sckaddr (const hcl_bch_t* str, hcl_oow_t len, hcl_sckaddr_t* sckaddr, hcl_scklen_t* scklen)
{
return hcl_bcharstosckaddr(HCL_NULL, str, len, sckaddr, scklen);
}
#else
#define hcl_uchars_to_sckaddr(str,len,sckaddr,scklen) hcl_ucharstosckaddr(HCL_NULL,str,len,sckaddr,scklen)
#define hcl_bchars_to_sckaddr(str,len,sckaddr,scklen) hcl_bcharstosckaddr(HCL_NULL,str,len,sckaddr,scklen)
#define hcl_uchars_to_sckaddr(str,len,sckaddr,scklen) hcl_ucharstosckaddr(HCL_NULL,str,len,sckaddr,scklen)
#define hcl_bchars_to_sckaddr(str,len,sckaddr,scklen) hcl_bcharstosckaddr(HCL_NULL,str,len,sckaddr,scklen)
#endif
#if defined(HCL_OOCH_IS_UCH)

336
lib/x-client.c Normal file
View File

@ -0,0 +1,336 @@
/*
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.
*/
#include "hcl-x.h"
#include "hcl-prv.h"
#include "hcl-tmr.h"
#include "hcl-xutl.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define HCL_SERVER_TOKEN_NAME_ALIGN 64
#define HCL_SERVER_WID_MAP_ALIGN 512
#define HCL_XPROTO_REPLY_BUF_SIZE 1300
#if defined(_WIN32)
# include <windows.h>
# include <tchar.h>
#elif defined(__OS2__)
# define INCL_DOSMODULEMGR
# define INCL_DOSPROCESS
# define INCL_DOSERRORS
# include <os2.h>
#elif defined(__DOS__)
# include <dos.h>
# include <time.h>
# include <signal.h>
#elif defined(macintosh)
# include <Timer.h>
#else
# if defined(HAVE_TIME_H)
# include <time.h>
# endif
# if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
# endif
# if defined(HAVE_SIGNAL_H)
# include <signal.h>
# endif
# if defined(HAVE_SYS_MMAN_H)
# include <sys/mman.h>
# endif
# if defined(HAVE_SYS_UIO_H)
# include <sys/uio.h>
# endif
# if defined(HAVE_SYS_EPOLL_H)
# include <sys/epoll.h>
# endif
# include <unistd.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <pthread.h>
# include <poll.h>
#endif
struct client_hcl_xtn_t
{
hcl_client_t* client;
};
typedef struct client_hcl_xtn_t client_hcl_xtn_t;
struct hcl_client_t
{
hcl_oow_t _instsize;
hcl_mmgr_t* _mmgr;
hcl_cmgr_t* _cmgr;
hcl_client_prim_t prim;
hcl_t* dummy_hcl;
hcl_errnum_t errnum;
struct
{
hcl_ooch_t buf[HCL_ERRMSG_CAPA];
hcl_oow_t len;
} errmsg;
struct
{
hcl_bitmask_t trait;
hcl_bitmask_t logmask;
} cfg;
};
/* ========================================================================= */
static void client_log_write_for_dummy (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
client_hcl_xtn_t* xtn = (client_hcl_xtn_t*)hcl_getxtn(hcl);
hcl_client_t* client;
client = xtn->client;
client->prim.log_write (client, mask, msg, len);
}
hcl_client_t* hcl_client_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_client_prim_t* prim, hcl_errnum_t* errnum)
{
hcl_client_t* client;
hcl_t* hcl;
client_hcl_xtn_t* xtn;
client = (hcl_client_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*client) + xtnsize);
if (!client)
{
if (errnum) *errnum = HCL_ESYSMEM;
return HCL_NULL;
}
hcl = hcl_openstdwithmmgr(mmgr, HCL_SIZEOF(*xtn), errnum);
if (!hcl)
{
HCL_MMGR_FREE (mmgr, client);
return HCL_NULL;
}
/* replace the vmprim.log_write function */
hcl->vmprim.log_write = client_log_write_for_dummy;
xtn = (client_hcl_xtn_t*)hcl_getxtn(hcl);
xtn->client = client;
HCL_MEMSET (client, 0, HCL_SIZEOF(*client) + xtnsize);
client->_instsize = HCL_SIZEOF(*client);
client->_mmgr = mmgr;
client->_cmgr = hcl_get_utf8_cmgr();
client->prim = *prim;
client->dummy_hcl = hcl;
client->cfg.logmask = ~(hcl_bitmask_t)0;
/* the dummy hcl is used for this client to perform primitive operations
* such as getting system time or logging. so the heap size doesn't
* need to be changed from the tiny value set above. */
hcl_setoption (client->dummy_hcl, HCL_LOG_MASK, &client->cfg.logmask);
hcl_setcmgr (client->dummy_hcl, client->_cmgr);
return client;
}
void hcl_client_close (hcl_client_t* client)
{
hcl_close (client->dummy_hcl);
HCL_MMGR_FREE (client->_mmgr, client);
}
int hcl_client_setoption (hcl_client_t* client, hcl_client_option_t id, const void* value)
{
switch (id)
{
case HCL_CLIENT_TRAIT:
client->cfg.trait = *(const hcl_bitmask_t*)value;
return 0;
case HCL_CLIENT_LOG_MASK:
client->cfg.logmask = *(const hcl_bitmask_t*)value;
if (client->dummy_hcl)
{
/* setting this affects the dummy hcl immediately.
* existing hcl instances inside worker threads won't get
* affected. new hcl instances to be created later
* is supposed to use the new value */
hcl_setoption (client->dummy_hcl, HCL_LOG_MASK, value);
}
return 0;
}
hcl_client_seterrnum (client, HCL_EINVAL);
return -1;
}
int hcl_client_getoption (hcl_client_t* client, hcl_client_option_t id, void* value)
{
switch (id)
{
case HCL_CLIENT_TRAIT:
*(hcl_bitmask_t*)value = client->cfg.trait;
return 0;
case HCL_CLIENT_LOG_MASK:
*(hcl_bitmask_t*)value = client->cfg.logmask;
return 0;
};
hcl_client_seterrnum (client, HCL_EINVAL);
return -1;
}
void* hcl_client_getxtn (hcl_client_t* client)
{
return (void*)((hcl_uint8_t*)client + client->_instsize);
}
hcl_mmgr_t* hcl_client_getmmgr (hcl_client_t* client)
{
return client->_mmgr;
}
hcl_cmgr_t* hcl_client_getcmgr (hcl_client_t* client)
{
return client->_cmgr;
}
void hcl_client_setcmgr (hcl_client_t* client, hcl_cmgr_t* cmgr)
{
client->_cmgr = cmgr;
}
hcl_errnum_t hcl_client_geterrnum (hcl_client_t* client)
{
return client->errnum;
}
const hcl_ooch_t* hcl_client_geterrstr (hcl_client_t* client)
{
return hcl_errnum_to_errstr(client->errnum);
}
const hcl_ooch_t* hcl_client_geterrmsg (hcl_client_t* client)
{
if (client->errmsg.len <= 0) return hcl_errnum_to_errstr(client->errnum);
return client->errmsg.buf;
}
void hcl_client_seterrnum (hcl_client_t* client, hcl_errnum_t errnum)
{
/*if (client->shuterr) return; */
client->errnum = errnum;
client->errmsg.len = 0;
}
void hcl_client_seterrbfmt (hcl_client_t* client, hcl_errnum_t errnum, const hcl_bch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_seterrbfmtv (client->dummy_hcl, errnum, fmt, ap);
va_end (ap);
HCL_ASSERT (client->dummy_hcl, HCL_COUNTOF(client->errmsg.buf) == HCL_COUNTOF(client->dummy_hcl->errmsg.buf));
client->errnum = errnum;
hcl_copy_oochars (client->errmsg.buf, client->dummy_hcl->errmsg.buf, HCL_COUNTOF(client->errmsg.buf));
client->errmsg.len = client->dummy_hcl->errmsg.len;
}
void hcl_client_seterrufmt (hcl_client_t* client, hcl_errnum_t errnum, const hcl_uch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_seterrufmtv (client->dummy_hcl, errnum, fmt, ap);
va_end (ap);
HCL_ASSERT (client->dummy_hcl, HCL_COUNTOF(client->errmsg.buf) == HCL_COUNTOF(client->dummy_hcl->errmsg.buf));
client->errnum = errnum;
hcl_copy_oochars (client->errmsg.buf, client->dummy_hcl->errmsg.buf, HCL_COUNTOF(client->errmsg.buf));
client->errmsg.len = client->dummy_hcl->errmsg.len;
}
/* ========================================================================= */
void hcl_client_logbfmt (hcl_client_t* client, hcl_bitmask_t mask, const hcl_bch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_logbfmtv (client->dummy_hcl, mask, fmt, ap);
va_end (ap);
}
void hcl_client_logufmt (hcl_client_t* client, hcl_bitmask_t mask, const hcl_uch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_logufmtv (client->dummy_hcl, mask, fmt, ap);
va_end (ap);
}
/* ========================================================================= */
void* hcl_client_allocmem (hcl_client_t* client, hcl_oow_t size)
{
void* ptr;
ptr = HCL_MMGR_ALLOC(client->_mmgr, size);
if (!ptr) hcl_client_seterrnum (client, HCL_ESYSMEM);
return ptr;
}
void* hcl_client_callocmem (hcl_client_t* client, hcl_oow_t size)
{
void* ptr;
ptr = HCL_MMGR_ALLOC(client->_mmgr, size);
if (!ptr) hcl_client_seterrnum (client, HCL_ESYSMEM);
else HCL_MEMSET (ptr, 0, size);
return ptr;
}
void* hcl_client_reallocmem (hcl_client_t* client, void* ptr, hcl_oow_t size)
{
ptr = HCL_MMGR_REALLOC(client->_mmgr, ptr, size);
if (!ptr) hcl_client_seterrnum (client, HCL_ESYSMEM);
return ptr;
}
void hcl_client_freemem (hcl_client_t* client, void* ptr)
{
HCL_MMGR_FREE (client->_mmgr, ptr);
}

195
lib/x-proto.c Normal file
View File

@ -0,0 +1,195 @@
/*
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.
*/
#include <hcl-x.h>
#include "hcl-prv.h"
enum hcl_xproto_rcv_state_t
{
HCL_XPROTO_RCV_HDR,
HCL_XPROTO_RCV_PLD
};
typedef enum hcl_xproto_rcv_state_t hcl_xproto_rcv_state_t;
struct hcl_xproto_t
{
hcl_oow_t _instsize;
hcl_mmgr_t* _mmgr;
hcl_xproto_cb_t _cb;
struct
{
hcl_xproto_rcv_state_t state;
hcl_oow_t len_needed;
unsigned int eof: 1;
hcl_oow_t len;
hcl_uint8_t buf[HCL_XPKT_MAX_PLD_LEN];
/* normalize header of hcl_xpkt_hdr_t with combined bits into separate placeholders */
struct
{
hcl_uint8_t id;
hcl_uint8_t type;
hcl_uint16_t len; /* this is wider than the len field of hcl_xpkt_hdr_t */
} hdr;
} rcv;
struct
{
} snd;
};
hcl_xproto_t* hcl_xproto_open (hcl_mmgr_t* mmgr, hcl_xproto_cb_t* cb, hcl_oow_t xtnsize)
{
hcl_xproto_t* proto;
proto = (hcl_xproto_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*proto) + xtnsize);
if (HCL_UNLIKELY(!proto)) return HCL_NULL;
HCL_MEMSET (proto, 0, HCL_SIZEOF(*proto));
proto->_instsize = HCL_SIZEOF(*proto);
proto->_mmgr = mmgr;
proto->_cb = *cb;
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_XPKT_HDR_LEN;
proto->rcv.eof = 0;
return proto;
}
void hcl_xproto_close (hcl_xproto_t* proto)
{
HCL_MMGR_FREE (proto->_mmgr, proto);
}
void* hcl_xproto_getxtn (hcl_xproto_t* proto)
{
return (proto + 1);
}
hcl_uint8_t* hcl_xproto_getbuf (hcl_xproto_t* proto, hcl_oow_t* capa)
{
*capa = HCL_COUNTOF(proto->rcv.buf) - proto->rcv.len;
return &proto->rcv.buf[proto->rcv.len];
}
int hcl_xproto_geteof (hcl_xproto_t* proto)
{
return proto->rcv.eof;
}
void hcl_xproto_seteof (hcl_xproto_t* proto, int v)
{
proto->rcv.eof = v;
}
void hcl_xproto_advbuf (hcl_xproto_t* proto, hcl_oow_t inc)
{
proto->rcv.len += inc;
}
int hcl_xproto_ready (hcl_xproto_t* proto)
{
/* has it received suffient data for processing? */
return proto->rcv.len >= proto->rcv.len_needed;
}
int hcl_xproto_process (hcl_xproto_t* proto)
{
int n;
hcl_xpkt_hdr_t* hdr;
switch (proto->rcv.state)
{
case HCL_XPROTO_RCV_HDR:
if (proto->rcv.len < HCL_XPKT_HDR_LEN) goto carry_on; /* need more data */
hdr = (hcl_xpkt_hdr_t*)proto->rcv.buf;
proto->rcv.hdr.id = hdr->id;
proto->rcv.hdr.type = hdr->type & 0x0F;
proto->rcv.hdr.len = (hcl_uint16_t)hdr->len | ((hcl_uint16_t)(hdr->type >> 4) << 8);
/* consume the header */
HCL_MEMMOVE (proto->rcv.buf, &proto->rcv.buf[HCL_XPKT_HDR_LEN], proto->rcv.len - HCL_XPKT_HDR_LEN);
proto->rcv.len -= HCL_XPKT_HDR_LEN;
/* switch to the payload mode */
if (proto->rcv.hdr.len > 0)
{
proto->rcv.state = HCL_XPROTO_RCV_PLD;
proto->rcv.len_needed = proto->rcv.hdr.len;
}
else
{
/* take shortcut */
/* TODO: convert handle_packet as call back */
n = proto->_cb.on_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
if (n <= -1) goto fail_with_errmsg;
if (n == 0) return 0;
}
break;
case HCL_XPROTO_RCV_PLD:
if (proto->rcv.len < proto->rcv.hdr.len) goto carry_on; /* need more payload data */
/* TODO: convert handle_packet as call back */
n = proto->_cb.on_packet(proto, proto->rcv.hdr.type, proto->rcv.buf, proto->rcv.hdr.len);
/* TODO: minimize the use of HCL_MEMOVE... use the buffer */
/* switch to the header mode */
if (proto->rcv.hdr.len > 0)
{
HCL_MEMMOVE (proto->rcv.buf, &proto->rcv.buf[proto->rcv.hdr.len], proto->rcv.len - proto->rcv.hdr.len);
proto->rcv.len -= proto->rcv.hdr.len;
}
proto->rcv.state = HCL_XPROTO_RCV_HDR;
proto->rcv.len_needed = HCL_XPKT_HDR_LEN;
if (n <= -1) goto fail_with_errmsg;
if (n == 0) return 0;
break;
default:
/*
hcl_seterrbfmt (hcl, HCL_EINTERN, "invalid request state %d", (int)proto->rcv.state);
*/
/* TODO: call back */
goto fail_with_errmsg;
}
carry_on:
return 1;
fail_with_errmsg:
// TODO: proper error handling
//send_proto_hcl_error (proto);
//HCL_LOG1 (hcl, SERVER_LOGMASK_ERROR, "Unable to compile .SCRIPT contents - %js\n", hcl_geterrmsg(worker->hcl));
return -1;
}

2285
lib/x-server.c Normal file

File diff suppressed because it is too large Load Diff