added HCL_IO_WRITE_BYTES
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
implemented it in the print handler
This commit is contained in:
parent
8514f0e590
commit
a5d96cc6eb
@ -122,7 +122,7 @@ static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode)
|
|||||||
|
|
||||||
static void gc_hcl (hcl_t* hcl)
|
static void gc_hcl (hcl_t* hcl)
|
||||||
{
|
{
|
||||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
/*xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);*/
|
||||||
/*if (xtn->sym_errstr) xtn->sym_errstr = hcl_moveoop(hcl, xtn->sym_errstr);*/
|
/*if (xtn->sym_errstr) xtn->sym_errstr = hcl_moveoop(hcl, xtn->sym_errstr);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
lib/fmt.c
18
lib/fmt.c
@ -1790,6 +1790,7 @@ static int print_bcs (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len)
|
|||||||
{
|
{
|
||||||
hcl_t* hcl = (hcl_t*)fmtout->ctx;
|
hcl_t* hcl = (hcl_t*)fmtout->ctx;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#if defined(HCL_OOCH_IS_UCH)
|
#if defined(HCL_OOCH_IS_UCH)
|
||||||
hcl_oow_t ucslen, bcslen;
|
hcl_oow_t ucslen, bcslen;
|
||||||
hcl_ooch_t ucsbuf[64], * ucsptr;
|
hcl_ooch_t ucsbuf[64], * ucsptr;
|
||||||
@ -1834,6 +1835,23 @@ static int print_bcs (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len)
|
|||||||
len -= hcl->io.outarg.xlen;
|
len -= hcl->io.outarg.xlen;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
hcl_bch_t* optr;
|
||||||
|
|
||||||
|
optr = (hcl_bch_t*)ptr;
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
hcl->io.outarg.ptr = optr;
|
||||||
|
hcl->io.outarg.len = len;
|
||||||
|
|
||||||
|
if (hcl->io.printer(hcl, HCL_IO_WRITE_BYTES, &hcl->io.outarg) <= -1) return -1;
|
||||||
|
if (hcl->io.outarg.xlen <= 0) return 0; /* end of stream. but not failure */
|
||||||
|
|
||||||
|
HCL_ASSERT (hcl, hcl->io.outarg.xlen <= len);
|
||||||
|
optr += hcl->io.outarg.xlen;
|
||||||
|
len -= hcl->io.outarg.xlen;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
|
162
lib/hcl-s.c
162
lib/hcl-s.c
@ -198,7 +198,7 @@ struct hcl_server_worker_t
|
|||||||
hcl_sckaddr_t peeraddr;
|
hcl_sckaddr_t peeraddr;
|
||||||
|
|
||||||
int claimed;
|
int claimed;
|
||||||
|
|
||||||
hcl_ntime_t alloc_time;
|
hcl_ntime_t alloc_time;
|
||||||
hcl_server_worker_state_t state;
|
hcl_server_worker_state_t state;
|
||||||
hcl_server_worker_opstate_t opstate;
|
hcl_server_worker_opstate_t opstate;
|
||||||
@ -241,7 +241,7 @@ struct hcl_server_t
|
|||||||
* the code must ensure that the logging functions are called in the
|
* the code must ensure that the logging functions are called in the
|
||||||
* context of the main server thraed only. error message setting is
|
* context of the main server thraed only. error message setting is
|
||||||
* also performed in the main thread context for the same reason.
|
* also performed in the main thread context for the same reason.
|
||||||
*
|
*
|
||||||
* however, you may have noticed mixed use of HCL_ASSERT with dummy_hcl
|
* however, you may have noticed mixed use of HCL_ASSERT with dummy_hcl
|
||||||
* in both the server thread context and the client thread contexts.
|
* in both the server thread context and the client thread contexts.
|
||||||
* it should be ok as assertion is only for debugging and it's operation
|
* it should be ok as assertion is only for debugging and it's operation
|
||||||
@ -327,7 +327,7 @@ static HCL_INLINE int open_input (hcl_t* hcl, hcl_iosrarg_t* arg)
|
|||||||
if (arg->includer)
|
if (arg->includer)
|
||||||
{
|
{
|
||||||
/* includee */
|
/* includee */
|
||||||
/* TOOD: Do i need to skip prepending the include path if the included path is an absolute path?
|
/* TOOD: Do i need to skip prepending the include path if the included path is an absolute path?
|
||||||
* it may be good for security if i don't skip it. we can lock the included files in a given directory */
|
* it may be good for security if i don't skip it. we can lock the included files in a given directory */
|
||||||
hcl_oow_t ucslen, bcslen, parlen;
|
hcl_oow_t ucslen, bcslen, parlen;
|
||||||
const hcl_bch_t* fn, * fb;
|
const hcl_bch_t* fn, * fb;
|
||||||
@ -404,7 +404,7 @@ static HCL_INLINE int open_input (hcl_t* hcl, hcl_iosrarg_t* arg)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (bb)
|
if (bb)
|
||||||
{
|
{
|
||||||
if (bb->fd >= 0 && bb->fd != xtn->proto->worker->sck) close (bb->fd);
|
if (bb->fd >= 0 && bb->fd != xtn->proto->worker->sck) close (bb->fd);
|
||||||
hcl_freemem (hcl, bb);
|
hcl_freemem (hcl, bb);
|
||||||
@ -461,7 +461,7 @@ start_over:
|
|||||||
|
|
||||||
bb->len += x;
|
bb->len += x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* main stream */
|
/* main stream */
|
||||||
hcl_server_t* server;
|
hcl_server_t* server;
|
||||||
@ -518,7 +518,7 @@ start_over:
|
|||||||
bcslen = bb->len;
|
bcslen = bb->len;
|
||||||
ucslen = HCL_COUNTOF(arg->buf);
|
ucslen = HCL_COUNTOF(arg->buf);
|
||||||
y = hcl_convbtooochars(hcl, bb->buf, &bcslen, arg->buf, &ucslen);
|
y = hcl_convbtooochars(hcl, bb->buf, &bcslen, arg->buf, &ucslen);
|
||||||
if (y <= -1 && ucslen <= 0)
|
if (y <= -1 && ucslen <= 0)
|
||||||
{
|
{
|
||||||
if (y == -3 && x != 0) goto start_over; /* incomplete sequence and not EOF yet */
|
if (y == -3 && x != 0) goto start_over; /* incomplete sequence and not EOF yet */
|
||||||
return -1;
|
return -1;
|
||||||
@ -574,12 +574,12 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
|||||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||||
hcl_iooutarg_t* outarg = (hcl_iooutarg_t*)arg;
|
hcl_iooutarg_t* outarg = (hcl_iooutarg_t*)arg;
|
||||||
|
|
||||||
if (hcl_server_proto_feed_reply(xtn->proto, outarg->ptr, outarg->len, 0) <= -1)
|
if (hcl_server_proto_feed_reply(xtn->proto, outarg->ptr, outarg->len, 0) <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: change error code and message. propagage the errormessage from proto */
|
/* TODO: change error code and message. propagage the errormessage from proto */
|
||||||
hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
|
hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
|
||||||
|
|
||||||
/* writing failure on the socket is a critical failure.
|
/* writing failure on the socket is a critical failure.
|
||||||
* execution must get aborted */
|
* execution must get aborted */
|
||||||
hcl_abort (hcl);
|
hcl_abort (hcl);
|
||||||
return -1;
|
return -1;
|
||||||
@ -588,6 +588,24 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case HCL_IO_WRITE_BYTES:
|
||||||
|
{
|
||||||
|
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||||
|
hcl_iooutarg_t* outarg = (hcl_iooutarg_t*)arg;
|
||||||
|
|
||||||
|
if (hcl_server_proto_feed_reply_bytes(xtn->proto, outarg->ptr, outarg->len, 0) <= -1)
|
||||||
|
{
|
||||||
|
/* TODO: change error code and message. propagage the errormessage from proto */
|
||||||
|
hcl_seterrbfmt (hcl, HCL_EIOERR, "failed to write message via proto");
|
||||||
|
|
||||||
|
/* writing failure on the socket is a critical failure.
|
||||||
|
* execution must get aborted */
|
||||||
|
hcl_abort (hcl);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
outarg->xlen = outarg->len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
hcl_seterrnum (hcl, HCL_EINTERN);
|
hcl_seterrnum (hcl, HCL_EINTERN);
|
||||||
return -1;
|
return -1;
|
||||||
@ -736,7 +754,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
iov[count].iov_base = cl,
|
iov[count].iov_base = cl,
|
||||||
iov[count++].iov_len = snprintf(cl, HCL_SIZEOF(cl), "%zu:", proto->reply.len);
|
iov[count++].iov_len = snprintf(cl, HCL_SIZEOF(cl), "%zu:", proto->reply.len);
|
||||||
}
|
}
|
||||||
iov[count].iov_base = proto->reply.buf;
|
iov[count].iov_base = proto->reply.buf;
|
||||||
iov[count++].iov_len = proto->reply.len;
|
iov[count++].iov_len = proto->reply.len;
|
||||||
@ -750,12 +768,12 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
|
|||||||
msg.msg_iovlen = count - index;
|
msg.msg_iovlen = count - index;
|
||||||
nwritten = sendmsg(proto->worker->sck, &msg, 0);
|
nwritten = sendmsg(proto->worker->sck, &msg, 0);
|
||||||
/*nwritten = writev(proto->worker->sck, (const struct iovec*)&iov[index], count - index);*/
|
/*nwritten = writev(proto->worker->sck, (const struct iovec*)&iov[index], count - index);*/
|
||||||
if (nwritten <= -1)
|
if (nwritten <= -1)
|
||||||
{
|
{
|
||||||
/* 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_LOG2 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to sendmsg on %d - %hs\n", proto->worker->sck, strerror(errno));
|
HCL_LOG2 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to sendmsg on %d - %hs\n", proto->worker->sck, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (index < count && (size_t)nwritten >= iov[index].iov_len)
|
while (index < count && (size_t)nwritten >= iov[index].iov_len)
|
||||||
@ -850,6 +868,24 @@ int hcl_server_proto_feed_reply (hcl_server_proto_t* proto, const hcl_ooch_t* pt
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hcl_server_proto_feed_reply_bytes (hcl_server_proto_t* proto, const hcl_bch_t* ptr, hcl_oow_t len, int escape)
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
if (escape && (*ptr == '\\' || *ptr == '\"'))
|
||||||
|
{
|
||||||
|
if (proto->reply.len >= HCL_COUNTOF(proto->reply.buf) && write_reply_chunk(proto) <=-1) return -1;
|
||||||
|
proto->reply.buf[proto->reply.len++] = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proto->reply.len >= HCL_COUNTOF(proto->reply.buf) && write_reply_chunk(proto) <=-1) return -1;
|
||||||
|
proto->reply.buf[proto->reply.len++] = *ptr++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int hcl_server_proto_end_reply (hcl_server_proto_t* proto, const hcl_ooch_t* failmsg)
|
int hcl_server_proto_end_reply (hcl_server_proto_t* proto, const hcl_ooch_t* failmsg)
|
||||||
{
|
{
|
||||||
HCL_ASSERT (proto->hcl, proto->reply.type == HCL_SERVER_PROTO_REPLY_CHUNKED);
|
HCL_ASSERT (proto->hcl, proto->reply.type == HCL_SERVER_PROTO_REPLY_CHUNKED);
|
||||||
@ -869,7 +905,7 @@ int hcl_server_proto_end_reply (hcl_server_proto_t* proto, const hcl_ooch_t* fai
|
|||||||
|
|
||||||
if (write_reply_chunk(proto) <= -1) return -1;
|
if (write_reply_chunk(proto) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* some chunks have beed emitted. but at the end, an error has occurred.
|
/* some chunks have beed emitted. but at the end, an error has occurred.
|
||||||
* send -1: as the last chunk. the receiver must rub out the reply
|
* send -1: as the last chunk. the receiver must rub out the reply
|
||||||
@ -936,7 +972,7 @@ static HCL_INLINE int is_digitchar (hcl_ooci_t c)
|
|||||||
|
|
||||||
static HCL_INLINE int read_char (hcl_server_proto_t* proto)
|
static HCL_INLINE int read_char (hcl_server_proto_t* proto)
|
||||||
{
|
{
|
||||||
if (proto->unread_count > 0)
|
if (proto->unread_count > 0)
|
||||||
{
|
{
|
||||||
proto->lxc = &proto->unread_lxc;
|
proto->lxc = &proto->unread_lxc;
|
||||||
proto->unread_count--;
|
proto->unread_count--;
|
||||||
@ -993,7 +1029,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c)
|
|||||||
|
|
||||||
capa = HCL_ALIGN_POW2(proto->tok.len + 1, HCL_SERVER_TOKEN_NAME_ALIGN);
|
capa = HCL_ALIGN_POW2(proto->tok.len + 1, HCL_SERVER_TOKEN_NAME_ALIGN);
|
||||||
tmp = (hcl_ooch_t*)hcl_server_reallocmem(proto->worker->server, proto->tok.ptr, capa * HCL_SIZEOF(*tmp));
|
tmp = (hcl_ooch_t*)hcl_server_reallocmem(proto->worker->server, proto->tok.ptr, capa * HCL_SIZEOF(*tmp));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
hcl_seterrbfmt (proto->hcl, HCL_ESYSMEM, "Out of memory in allocating token buffer");
|
hcl_seterrbfmt (proto->hcl, HCL_ESYSMEM, "Out of memory in allocating token buffer");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1013,13 +1049,13 @@ static void classify_current_ident_token (hcl_server_proto_t* proto)
|
|||||||
{
|
{
|
||||||
hcl_server_proto_token_type_t type;
|
hcl_server_proto_token_type_t type;
|
||||||
hcl_ooch_t name[32];
|
hcl_ooch_t name[32];
|
||||||
} tab[] =
|
} tab[] =
|
||||||
{
|
{
|
||||||
{ HCL_SERVER_PROTO_TOKEN_BEGIN, { '.','B','E','G','I','N','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_BEGIN, { '.','B','E','G','I','N','\0' } },
|
||||||
{ HCL_SERVER_PROTO_TOKEN_END, { '.','E','N','D','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_END, { '.','E','N','D','\0' } },
|
||||||
{ HCL_SERVER_PROTO_TOKEN_SCRIPT, { '.','S','C','R','I','P','T','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_SCRIPT, { '.','S','C','R','I','P','T','\0' } },
|
||||||
{ HCL_SERVER_PROTO_TOKEN_EXIT, { '.','E','X','I','T','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_EXIT, { '.','E','X','I','T','\0' } },
|
||||||
|
|
||||||
{ HCL_SERVER_PROTO_TOKEN_KILL_WORKER, { '.','K','I','L','L','-','W','O','R','K','E','R','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_KILL_WORKER, { '.','K','I','L','L','-','W','O','R','K','E','R','\0' } },
|
||||||
{ HCL_SERVER_PROTO_TOKEN_SHOW_WORKERS, { '.','S','H','O','W','-','W','O','R','K','E','R','S','\0' } },
|
{ HCL_SERVER_PROTO_TOKEN_SHOW_WORKERS, { '.','S','H','O','W','-','W','O','R','K','E','R','S','\0' } },
|
||||||
/* TODO: add more */
|
/* TODO: add more */
|
||||||
@ -1028,7 +1064,7 @@ static void classify_current_ident_token (hcl_server_proto_t* proto)
|
|||||||
|
|
||||||
for (i = 0; i < HCL_COUNTOF(tab); i++)
|
for (i = 0; i < HCL_COUNTOF(tab); i++)
|
||||||
{
|
{
|
||||||
if (hcl_comp_oochars_oocstr(proto->tok.ptr, proto->tok.len, tab[i].name) == 0)
|
if (hcl_comp_oochars_oocstr(proto->tok.ptr, proto->tok.len, tab[i].name) == 0)
|
||||||
{
|
{
|
||||||
SET_TOKEN_TYPE (proto, tab[i].type);
|
SET_TOKEN_TYPE (proto, tab[i].type);
|
||||||
break;
|
break;
|
||||||
@ -1106,7 +1142,7 @@ static int get_token (hcl_server_proto_t* proto)
|
|||||||
|
|
||||||
static void exec_runtime_handler (hcl_tmr_t* tmr, const hcl_ntime_t* now, hcl_tmr_event_t* evt)
|
static void exec_runtime_handler (hcl_tmr_t* tmr, const hcl_ntime_t* now, hcl_tmr_event_t* evt)
|
||||||
{
|
{
|
||||||
/* [NOTE] this handler is executed in the main server thread
|
/* [NOTE] this handler is executed in the main server thread
|
||||||
* when it calls hcl_tmr_fire(). */
|
* when it calls hcl_tmr_fire(). */
|
||||||
|
|
||||||
hcl_server_proto_t* proto;
|
hcl_server_proto_t* proto;
|
||||||
@ -1118,14 +1154,14 @@ static void exec_runtime_handler (hcl_tmr_t* tmr, const hcl_ntime_t* now, hcl_tm
|
|||||||
|
|
||||||
static void exec_runtime_updater (hcl_tmr_t* tmr, hcl_tmr_index_t old_index, hcl_tmr_index_t new_index, hcl_tmr_event_t* evt)
|
static void exec_runtime_updater (hcl_tmr_t* tmr, hcl_tmr_index_t old_index, hcl_tmr_index_t new_index, hcl_tmr_event_t* evt)
|
||||||
{
|
{
|
||||||
/* [NOTE] this handler is executed in the main server thread
|
/* [NOTE] this handler is executed in the main server thread
|
||||||
* when it calls hcl_tmr_fire() */
|
* when it calls hcl_tmr_fire() */
|
||||||
|
|
||||||
hcl_server_proto_t* proto;
|
hcl_server_proto_t* proto;
|
||||||
proto = (hcl_server_proto_t*)evt->ctx;
|
proto = (hcl_server_proto_t*)evt->ctx;
|
||||||
HCL_ASSERT (proto->hcl, proto->exec_runtime_event_index == old_index);
|
HCL_ASSERT (proto->hcl, proto->exec_runtime_event_index == old_index);
|
||||||
|
|
||||||
/* the event is being removed by hcl_tmr_fire() or by hcl_tmr_delete()
|
/* 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. */
|
* if new_index is HCL_TMR_INVALID_INDEX. it's being updated if not. */
|
||||||
proto->exec_runtime_event_index = new_index;
|
proto->exec_runtime_event_index = new_index;
|
||||||
}
|
}
|
||||||
@ -1133,7 +1169,7 @@ static void exec_runtime_updater (hcl_tmr_t* tmr, hcl_tmr_index_t old_index, hcl
|
|||||||
static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmout)
|
static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmout)
|
||||||
{
|
{
|
||||||
/* [NOTE] this is executed in the worker thread */
|
/* [NOTE] this is executed in the worker thread */
|
||||||
|
|
||||||
hcl_tmr_event_t event;
|
hcl_tmr_event_t event;
|
||||||
hcl_tmr_index_t index;
|
hcl_tmr_index_t index;
|
||||||
hcl_server_t* server;
|
hcl_server_t* server;
|
||||||
@ -1165,7 +1201,7 @@ static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmou
|
|||||||
static void delete_exec_timer (hcl_server_proto_t* proto)
|
static void delete_exec_timer (hcl_server_proto_t* proto)
|
||||||
{
|
{
|
||||||
/* [NOTE] this is executed in the worker thread. if the event has been fired
|
/* [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, proto->exec_runtime_event_index should be
|
||||||
* HCL_TMR_INVALID_INDEX as set by exec_runtime_handler */
|
* HCL_TMR_INVALID_INDEX as set by exec_runtime_handler */
|
||||||
hcl_server_t* server;
|
hcl_server_t* server;
|
||||||
|
|
||||||
@ -1174,7 +1210,7 @@ static void delete_exec_timer (hcl_server_proto_t* proto)
|
|||||||
pthread_mutex_lock (&server->tmr_mutex);
|
pthread_mutex_lock (&server->tmr_mutex);
|
||||||
if (proto->exec_runtime_event_index != HCL_TMR_INVALID_INDEX)
|
if (proto->exec_runtime_event_index != HCL_TMR_INVALID_INDEX)
|
||||||
{
|
{
|
||||||
/* the event has not been fired yet. let's delete it
|
/* 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 */
|
* 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_tmr_delete (server->tmr, proto->exec_runtime_event_index);
|
||||||
@ -1214,7 +1250,7 @@ static int execute_script (hcl_server_proto_t* proto, const hcl_bch_t* trigger)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcl_server_proto_end_reply(proto, failmsg) <= -1)
|
if (hcl_server_proto_end_reply(proto, failmsg) <= -1)
|
||||||
{
|
{
|
||||||
HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "Cannot finalize reply for %hs\n", trigger);
|
HCL_LOG1 (proto->hcl, SERVER_LOGMASK_ERROR, "Cannot finalize reply for %hs\n", trigger);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1244,7 +1280,7 @@ static void reformat_synerr (hcl_t* hcl)
|
|||||||
orgmsg = hcl_backuperrmsg(hcl);
|
orgmsg = hcl_backuperrmsg(hcl);
|
||||||
hcl_seterrbfmt (
|
hcl_seterrbfmt (
|
||||||
hcl, HCL_ESYNERR,
|
hcl, HCL_ESYNERR,
|
||||||
"%js%hs%.*js at %js%hsline %zu column %zu",
|
"%js%hs%.*js at %js%hsline %zu column %zu",
|
||||||
orgmsg,
|
orgmsg,
|
||||||
(synerr.tgt.len > 0? " near ": ""),
|
(synerr.tgt.len > 0? " near ": ""),
|
||||||
synerr.tgt.len, synerr.tgt.val,
|
synerr.tgt.len, synerr.tgt.val,
|
||||||
@ -1299,7 +1335,7 @@ static int kill_server_worker (hcl_server_proto_t* proto, hcl_oow_t wid)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
worker = server->wid_map.ptr[wid].u.worker;
|
worker = server->wid_map.ptr[wid].u.worker;
|
||||||
if (!worker)
|
if (!worker)
|
||||||
{
|
{
|
||||||
hcl_server_seterrnum (server, HCL_ENOENT);
|
hcl_server_seterrnum (server, HCL_ENOENT);
|
||||||
xret = -1;
|
xret = -1;
|
||||||
@ -1347,9 +1383,9 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
|||||||
hcl_seterrbfmt (proto->hcl, HCL_EINVAL, "No new line after .EXIT");
|
hcl_seterrbfmt (proto->hcl, HCL_EINVAL, "No new line after .EXIT");
|
||||||
goto fail_with_errmsg;
|
goto fail_with_errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .EXIT\n");
|
HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .EXIT\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1394,7 +1430,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
|||||||
/* i must not jump to fail_with_errmsg when execute_script() fails.
|
/* i must not jump to fail_with_errmsg when execute_script() fails.
|
||||||
* it may have produced some normal output already. so the function
|
* it may have produced some normal output already. so the function
|
||||||
* is supposed to handle an error in itself */
|
* is supposed to handle an error in itself */
|
||||||
if (execute_script(proto, ".END") <= -1) return -1;
|
if (execute_script(proto, ".END") <= -1) return -1;
|
||||||
proto->req.state = HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL;
|
proto->req.state = HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1404,7 +1440,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
|||||||
hcl_ooch_t ch;
|
hcl_ooch_t ch;
|
||||||
hcl_oow_t feed_count = 0;
|
hcl_oow_t feed_count = 0;
|
||||||
|
|
||||||
if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL)
|
if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL)
|
||||||
{
|
{
|
||||||
hcl_setbasesrloc (proto->hcl, 1, 1);
|
hcl_setbasesrloc (proto->hcl, 1, 1);
|
||||||
hcl_reset(proto->hcl);
|
hcl_reset(proto->hcl);
|
||||||
@ -1475,7 +1511,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
|||||||
hcl_seterrbfmt (proto->hcl, HCL_EINVAL, "No new line after .SHOW-WORKERS");
|
hcl_seterrbfmt (proto->hcl, HCL_EINVAL, "No new line after .SHOW-WORKERS");
|
||||||
goto fail_with_errmsg;
|
goto fail_with_errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
hcl_server_proto_start_reply (proto);
|
hcl_server_proto_start_reply (proto);
|
||||||
proto->worker->opstate = HCL_SERVER_WORKER_OPSTATE_EXECUTE;
|
proto->worker->opstate = HCL_SERVER_WORKER_OPSTATE_EXECUTE;
|
||||||
show_server_workers (proto);
|
show_server_workers (proto);
|
||||||
@ -1484,7 +1520,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
|||||||
HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .SHOW-WORKERS\n");
|
HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "Unable to finalize reply for .SHOW-WORKERS\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCL_SERVER_PROTO_TOKEN_KILL_WORKER:
|
case HCL_SERVER_PROTO_TOKEN_KILL_WORKER:
|
||||||
@ -1552,7 +1588,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
hcl_bitmask_t trait;
|
hcl_bitmask_t trait;
|
||||||
|
|
||||||
server = (hcl_server_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*server) + xtnsize);
|
server = (hcl_server_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*server) + xtnsize);
|
||||||
if (!server)
|
if (!server)
|
||||||
{
|
{
|
||||||
if (errnum) *errnum = HCL_ESYSMEM;
|
if (errnum) *errnum = HCL_ESYSMEM;
|
||||||
return HCL_NULL;
|
return HCL_NULL;
|
||||||
@ -1579,7 +1615,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
|
|
||||||
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
||||||
fcv = fcntl(pfd[0], F_GETFD, 0);
|
fcv = fcntl(pfd[0], F_GETFD, 0);
|
||||||
if (fcv >= 0)
|
if (fcv >= 0)
|
||||||
{
|
{
|
||||||
#if defined(O_NONBLOCK)
|
#if defined(O_NONBLOCK)
|
||||||
fcv |= O_NONBLOCK;
|
fcv |= O_NONBLOCK;
|
||||||
@ -1591,7 +1627,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
}
|
}
|
||||||
|
|
||||||
fcv = fcntl(pfd[1], F_GETFD, 0);
|
fcv = fcntl(pfd[1], F_GETFD, 0);
|
||||||
if (fcv >= 0)
|
if (fcv >= 0)
|
||||||
{
|
{
|
||||||
#if defined(O_NONBLOCK)
|
#if defined(O_NONBLOCK)
|
||||||
fcv |= O_NONBLOCK;
|
fcv |= O_NONBLOCK;
|
||||||
@ -1602,7 +1638,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
fcntl(pfd[1], F_SETFD, fcv);
|
fcntl(pfd[1], F_SETFD, fcv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xtn = (server_hcl_xtn_t*)hcl_getxtn(hcl);
|
xtn = (server_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||||
xtn->server = server;
|
xtn->server = server;
|
||||||
|
|
||||||
@ -1615,7 +1651,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
server->tmr = tmr;
|
server->tmr = tmr;
|
||||||
|
|
||||||
server->cfg.logmask = ~(hcl_bitmask_t)0;
|
server->cfg.logmask = ~(hcl_bitmask_t)0;
|
||||||
server->cfg.worker_stack_size = 512000UL;
|
server->cfg.worker_stack_size = 512000UL;
|
||||||
server->cfg.actor_heap_size = 512000UL;
|
server->cfg.actor_heap_size = 512000UL;
|
||||||
|
|
||||||
HCL_INIT_NTIME (&server->cfg.worker_idle_timeout, 0, 0);
|
HCL_INIT_NTIME (&server->cfg.worker_idle_timeout, 0, 0);
|
||||||
@ -1634,7 +1670,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
pthread_mutex_init (&server->log_mutex, HCL_NULL);
|
pthread_mutex_init (&server->log_mutex, HCL_NULL);
|
||||||
|
|
||||||
/* the dummy hcl is used for this server to perform primitive operations
|
/* the dummy hcl is used for this server to perform primitive operations
|
||||||
* such as getting system time or logging. so the heap size doesn't
|
* such as getting system time or logging. so the heap size doesn't
|
||||||
* need to be changed from the tiny value set above. */
|
* need to be changed from the tiny value set above. */
|
||||||
hcl_setoption (server->dummy_hcl, HCL_LOG_MASK, &server->cfg.logmask);
|
hcl_setoption (server->dummy_hcl, HCL_LOG_MASK, &server->cfg.logmask);
|
||||||
hcl_setcmgr (server->dummy_hcl, hcl_server_getcmgr(server));
|
hcl_setcmgr (server->dummy_hcl, hcl_server_getcmgr(server));
|
||||||
@ -1646,7 +1682,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
|||||||
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
/* NOTE: pipe should be closed if jump to here is made after pipe() above */
|
/* NOTE: pipe should be closed if jump to here is made after pipe() above */
|
||||||
if (tmr) hcl_tmr_close (tmr);
|
if (tmr) hcl_tmr_close (tmr);
|
||||||
@ -1669,7 +1705,7 @@ void hcl_server_close (hcl_server_t* server)
|
|||||||
server->wid_map.free_first = HCL_SERVER_WID_INVALID;
|
server->wid_map.free_first = HCL_SERVER_WID_INVALID;
|
||||||
server->wid_map.free_last = HCL_SERVER_WID_INVALID;
|
server->wid_map.free_last = HCL_SERVER_WID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_destroy (&server->log_mutex);
|
pthread_mutex_destroy (&server->log_mutex);
|
||||||
pthread_mutex_destroy (&server->tmr_mutex);
|
pthread_mutex_destroy (&server->tmr_mutex);
|
||||||
pthread_mutex_destroy (&server->worker_mutex);
|
pthread_mutex_destroy (&server->worker_mutex);
|
||||||
@ -1772,10 +1808,10 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck, con
|
|||||||
worker->sck = cli_sck;
|
worker->sck = cli_sck;
|
||||||
worker->peeraddr = *peeraddr;
|
worker->peeraddr = *peeraddr;
|
||||||
worker->server = server;
|
worker->server = server;
|
||||||
|
|
||||||
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??? */
|
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??? */
|
||||||
|
|
||||||
if (server->wid_map.free_first == HCL_SERVER_WID_INVALID && prepare_to_acquire_wid(server) <= -1)
|
if (server->wid_map.free_first == HCL_SERVER_WID_INVALID && prepare_to_acquire_wid(server) <= -1)
|
||||||
{
|
{
|
||||||
hcl_server_freemem (server, worker);
|
hcl_server_freemem (server, worker);
|
||||||
return HCL_NULL;
|
return HCL_NULL;
|
||||||
@ -1787,7 +1823,7 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck, con
|
|||||||
|
|
||||||
static void close_worker_socket (hcl_server_worker_t* worker)
|
static void close_worker_socket (hcl_server_worker_t* worker)
|
||||||
{
|
{
|
||||||
if (worker->sck >= 0)
|
if (worker->sck >= 0)
|
||||||
{
|
{
|
||||||
if (worker->proto)
|
if (worker->proto)
|
||||||
{
|
{
|
||||||
@ -1806,7 +1842,7 @@ static void close_worker_socket (hcl_server_worker_t* worker)
|
|||||||
static void free_worker (hcl_server_worker_t* worker)
|
static void free_worker (hcl_server_worker_t* worker)
|
||||||
{
|
{
|
||||||
close_worker_socket (worker);
|
close_worker_socket (worker);
|
||||||
|
|
||||||
if (worker->proto)
|
if (worker->proto)
|
||||||
{
|
{
|
||||||
HCL_LOG1 (worker->proto->hcl, SERVER_LOGMASK_INFO, "Killing worker [%zu]\n", worker->wid);
|
HCL_LOG1 (worker->proto->hcl, SERVER_LOGMASK_INFO, "Killing worker [%zu]\n", worker->wid);
|
||||||
@ -1847,7 +1883,7 @@ static void add_worker_to_server (hcl_server_t* server, hcl_server_worker_state_
|
|||||||
static void zap_worker_in_server (hcl_server_t* server, hcl_server_worker_t* worker)
|
static void zap_worker_in_server (hcl_server_t* server, hcl_server_worker_t* worker)
|
||||||
{
|
{
|
||||||
hcl_server_worker_state_t wstate;
|
hcl_server_worker_state_t wstate;
|
||||||
|
|
||||||
HCL_ASSERT (server->dummy_hcl, worker->server == server);
|
HCL_ASSERT (server->dummy_hcl, worker->server == server);
|
||||||
|
|
||||||
wstate = worker->state;
|
wstate = worker->state;
|
||||||
@ -1887,7 +1923,7 @@ static void* worker_main (void* ctx)
|
|||||||
while (!server->stopreq)
|
while (!server->stopreq)
|
||||||
{
|
{
|
||||||
worker->opstate = HCL_SERVER_WORKER_OPSTATE_WAIT;
|
worker->opstate = HCL_SERVER_WORKER_OPSTATE_WAIT;
|
||||||
if (hcl_server_proto_handle_request(worker->proto) <= 0)
|
if (hcl_server_proto_handle_request(worker->proto) <= 0)
|
||||||
{
|
{
|
||||||
worker->opstate = HCL_SERVER_WORKER_OPSTATE_ERROR;
|
worker->opstate = HCL_SERVER_WORKER_OPSTATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -1898,7 +1934,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_worker_socket (worker);
|
||||||
if (!worker->claimed)
|
if (!worker->claimed)
|
||||||
{
|
{
|
||||||
zap_worker_in_server (server, worker);
|
zap_worker_in_server (server, worker);
|
||||||
@ -1917,7 +1953,7 @@ static void purge_all_workers (hcl_server_t* server, hcl_server_worker_state_t w
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock (&server->worker_mutex);
|
pthread_mutex_lock (&server->worker_mutex);
|
||||||
worker = server->worker_list[wstate].head;
|
worker = server->worker_list[wstate].head;
|
||||||
if (worker)
|
if (worker)
|
||||||
{
|
{
|
||||||
zap_worker_in_server (server, worker);
|
zap_worker_in_server (server, worker);
|
||||||
worker->claimed = 1;
|
worker->claimed = 1;
|
||||||
@ -1953,7 +1989,7 @@ static void set_err_with_syserr (hcl_server_t* server, int syserr_type, int syse
|
|||||||
hcl_errnum_t errnum;
|
hcl_errnum_t errnum;
|
||||||
hcl_oow_t tmplen, tmplen2;
|
hcl_oow_t tmplen, tmplen2;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
static hcl_bch_t b_dash[] = { ' ', '-', ' ', '\0' };
|
static hcl_bch_t b_dash[] = { ' ', '-', ' ', '\0' };
|
||||||
static hcl_uch_t u_dash[] = { ' ', '-', ' ', '\0' };
|
static hcl_uch_t u_dash[] = { ' ', '-', ' ', '\0' };
|
||||||
|
|
||||||
@ -2072,7 +2108,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs)
|
|||||||
/* [NOTE] no whitespaces are allowed before and after a comma */
|
/* [NOTE] no whitespaces are allowed before and after a comma */
|
||||||
|
|
||||||
sck_fam = hcl_bchars_to_sckaddr(addr_ptr, addr_len, &srv_addr, &srv_len);
|
sck_fam = hcl_bchars_to_sckaddr(addr_ptr, addr_len, &srv_addr, &srv_len);
|
||||||
if (sck_fam <= -1)
|
if (sck_fam <= -1)
|
||||||
{
|
{
|
||||||
hcl_server_seterrbfmt (server, HCL_EINVAL, "unable to convert address - %.*hs", addr_len, addr_ptr);
|
hcl_server_seterrbfmt (server, HCL_EINVAL, "unable to convert address - %.*hs", addr_len, addr_ptr);
|
||||||
HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server));
|
HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server));
|
||||||
@ -2092,7 +2128,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs)
|
|||||||
|
|
||||||
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
||||||
fcv = fcntl(srv_fd, F_GETFD, 0);
|
fcv = fcntl(srv_fd, F_GETFD, 0);
|
||||||
if (fcv >= 0)
|
if (fcv >= 0)
|
||||||
{
|
{
|
||||||
#if defined(O_NONBLOCK)
|
#if defined(O_NONBLOCK)
|
||||||
fcv |= O_NONBLOCK;
|
fcv |= O_NONBLOCK;
|
||||||
@ -2245,7 +2281,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
|
|||||||
|
|
||||||
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
#if defined(O_NONBLOCK) || defined(O_CLOEXEC)
|
||||||
fcv = fcntl(cli_fd, F_GETFD, 0);
|
fcv = fcntl(cli_fd, F_GETFD, 0);
|
||||||
if (fcv >= 0)
|
if (fcv >= 0)
|
||||||
{
|
{
|
||||||
#if defined(O_NONBLOCK)
|
#if defined(O_NONBLOCK)
|
||||||
fcv &= ~O_NONBLOCK; // force the accepted socket to be blocking
|
fcv &= ~O_NONBLOCK; // force the accepted socket to be blocking
|
||||||
@ -2263,7 +2299,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
|
|||||||
pthread_mutex_lock (&server->worker_mutex);
|
pthread_mutex_lock (&server->worker_mutex);
|
||||||
flood = (server->worker_list[HCL_SERVER_WORKER_STATE_ALIVE].count >= server->cfg.worker_max_count);
|
flood = (server->worker_list[HCL_SERVER_WORKER_STATE_ALIVE].count >= server->cfg.worker_max_count);
|
||||||
pthread_mutex_unlock (&server->worker_mutex);
|
pthread_mutex_unlock (&server->worker_mutex);
|
||||||
if (flood)
|
if (flood)
|
||||||
{
|
{
|
||||||
HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "Not accepting connection for too many workers - socket %d\n", cli_fd);
|
HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "Not accepting connection for too many workers - socket %d\n", cli_fd);
|
||||||
goto drop_connection;
|
goto drop_connection;
|
||||||
@ -2313,8 +2349,8 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
|||||||
if (server->dummy_hcl)
|
if (server->dummy_hcl)
|
||||||
{
|
{
|
||||||
/* setting this affects the dummy hcl immediately.
|
/* setting this affects the dummy hcl immediately.
|
||||||
* existing hcl instances inside worker threads won't get
|
* existing hcl instances inside worker threads won't get
|
||||||
* affected. new hcl instances to be created later
|
* affected. new hcl instances to be created later
|
||||||
* is supposed to use the new value */
|
* is supposed to use the new value */
|
||||||
hcl_bitmask_t trait;
|
hcl_bitmask_t trait;
|
||||||
|
|
||||||
@ -2329,11 +2365,11 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
|||||||
|
|
||||||
case HCL_SERVER_LOG_MASK:
|
case HCL_SERVER_LOG_MASK:
|
||||||
server->cfg.logmask = *(const hcl_bitmask_t*)value;
|
server->cfg.logmask = *(const hcl_bitmask_t*)value;
|
||||||
if (server->dummy_hcl)
|
if (server->dummy_hcl)
|
||||||
{
|
{
|
||||||
/* setting this affects the dummy hcl immediately.
|
/* setting this affects the dummy hcl immediately.
|
||||||
* existing hcl instances inside worker threads won't get
|
* existing hcl instances inside worker threads won't get
|
||||||
* affected. new hcl instances to be created later
|
* affected. new hcl instances to be created later
|
||||||
* is supposed to use the new value */
|
* is supposed to use the new value */
|
||||||
hcl_setoption (server->dummy_hcl, HCL_LOG_MASK, value);
|
hcl_setoption (server->dummy_hcl, HCL_LOG_MASK, value);
|
||||||
}
|
}
|
||||||
@ -2342,11 +2378,11 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
|||||||
case HCL_SERVER_WORKER_MAX_COUNT:
|
case HCL_SERVER_WORKER_MAX_COUNT:
|
||||||
server->cfg.worker_max_count = *(hcl_oow_t*)value;
|
server->cfg.worker_max_count = *(hcl_oow_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HCL_SERVER_WORKER_STACK_SIZE:
|
case HCL_SERVER_WORKER_STACK_SIZE:
|
||||||
server->cfg.worker_stack_size = *(hcl_oow_t*)value;
|
server->cfg.worker_stack_size = *(hcl_oow_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
|
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
|
||||||
server->cfg.worker_idle_timeout = *(hcl_ntime_t*)value;
|
server->cfg.worker_idle_timeout = *(hcl_ntime_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2354,7 +2390,7 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
|||||||
case HCL_SERVER_ACTOR_HEAP_SIZE:
|
case HCL_SERVER_ACTOR_HEAP_SIZE:
|
||||||
server->cfg.actor_heap_size = *(hcl_oow_t*)value;
|
server->cfg.actor_heap_size = *(hcl_oow_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HCL_SERVER_ACTOR_MAX_RUNTIME:
|
case HCL_SERVER_ACTOR_MAX_RUNTIME:
|
||||||
server->cfg.actor_max_runtime = *(hcl_ntime_t*)value;
|
server->cfg.actor_max_runtime = *(hcl_ntime_t*)value;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2391,7 +2427,7 @@ int hcl_server_getoption (hcl_server_t* server, hcl_server_option_t id, void* va
|
|||||||
case HCL_SERVER_WORKER_STACK_SIZE:
|
case HCL_SERVER_WORKER_STACK_SIZE:
|
||||||
*(hcl_oow_t*)value = server->cfg.worker_stack_size;
|
*(hcl_oow_t*)value = server->cfg.worker_stack_size;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
|
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
|
||||||
*(hcl_ntime_t*)value = server->cfg.worker_idle_timeout;
|
*(hcl_ntime_t*)value = server->cfg.worker_idle_timeout;
|
||||||
return 0;
|
return 0;
|
||||||
|
40
lib/hcl.h
40
lib/hcl.h
@ -627,7 +627,7 @@ struct hcl_context_t
|
|||||||
|
|
||||||
/* the initial context is created with the initial function object in this field.
|
/* the initial context is created with the initial function object in this field.
|
||||||
* a function-based context is created with the activating function object.
|
* a function-based context is created with the activating function object.
|
||||||
* a block-based context is created with the function object that the base field of
|
* a block-based context is created with the function object that the base field of
|
||||||
* the home context of the activating block context points to. */
|
* the home context of the activating block context points to. */
|
||||||
hcl_oop_function_t base; /* function */
|
hcl_oop_function_t base; /* function */
|
||||||
|
|
||||||
@ -653,11 +653,11 @@ struct hcl_context_t
|
|||||||
/* instance variable access instructions hold the index to a variable within
|
/* instance variable access instructions hold the index to a variable within
|
||||||
* the the containing class. If the class inherits from a superclass and the
|
* the the containing class. If the class inherits from a superclass and the
|
||||||
* superclass chain contains instance variables, the actual index must be
|
* superclass chain contains instance variables, the actual index must be
|
||||||
* added with the number of instance variables in the superclass chain.
|
* added with the number of instance variables in the superclass chain.
|
||||||
*
|
*
|
||||||
* for example, the following instruction accesses the instance variable slot
|
* for example, the following instruction accesses the instance variable slot
|
||||||
* at index 3. if the class of the instance has 4 instance variables in the
|
* at index 3. if the class of the instance has 4 instance variables in the
|
||||||
* superclass side, the method context activated has 4 in thie field.
|
* superclass side, the method context activated has 4 in thie field.
|
||||||
* therefore, the instruction accesses the instance variable slot at index 7.
|
* therefore, the instruction accesses the instance variable slot at index 7.
|
||||||
* push_ivar 3
|
* push_ivar 3
|
||||||
* the debug output shows this instruction as "push_ivar 3; [4]"
|
* the debug output shows this instruction as "push_ivar 3; [4]"
|
||||||
@ -717,7 +717,7 @@ struct hcl_process_t
|
|||||||
|
|
||||||
/* == variable indexed part == */
|
/* == variable indexed part == */
|
||||||
hcl_oop_t slot[1]; /* process stack */
|
hcl_oop_t slot[1]; /* process stack */
|
||||||
|
|
||||||
/* after the process stack comes the exception stack.
|
/* after the process stack comes the exception stack.
|
||||||
* the exception stack is composed of instruction pointers and some context values.
|
* the exception stack is composed of instruction pointers and some context values.
|
||||||
* the instruction pointers are OOPs of small integers. safe without GC.
|
* the instruction pointers are OOPs of small integers. safe without GC.
|
||||||
@ -878,7 +878,7 @@ struct hcl_class_t
|
|||||||
|
|
||||||
/* [0] - instance methods, MethodDictionary
|
/* [0] - instance methods, MethodDictionary
|
||||||
* [1] - class methods, MethodDictionary */
|
* [1] - class methods, MethodDictionary */
|
||||||
hcl_oop_dic_t mthdic[2];
|
hcl_oop_dic_t mthdic[2];
|
||||||
|
|
||||||
hcl_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
hcl_oop_nsdic_t nsup; /* pointer to the upper namespace */
|
||||||
hcl_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
hcl_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */
|
||||||
@ -904,9 +904,9 @@ struct hcl_class_t
|
|||||||
hcl_oop_t trsize; /* trailer size for new instances */
|
hcl_oop_t trsize; /* trailer size for new instances */
|
||||||
hcl_oop_t trgc; /* trailer gc callback */
|
hcl_oop_t trgc; /* trailer gc callback */
|
||||||
|
|
||||||
/* [0] - initial values for instance variables of new instances
|
/* [0] - initial values for instance variables of new instances
|
||||||
* [1] - initial values for class instance variables */
|
* [1] - initial values for class instance variables */
|
||||||
hcl_oop_t initv[2];
|
hcl_oop_t initv[2];
|
||||||
#endif
|
#endif
|
||||||
/* indexed part afterwards */
|
/* indexed part afterwards */
|
||||||
hcl_oop_t cvar[1]; /* class instance variables and class variables. */
|
hcl_oop_t cvar[1]; /* class instance variables and class variables. */
|
||||||
@ -1198,6 +1198,7 @@ enum hcl_iocmd_t
|
|||||||
HCL_IO_CLOSE,
|
HCL_IO_CLOSE,
|
||||||
HCL_IO_READ,
|
HCL_IO_READ,
|
||||||
HCL_IO_WRITE,
|
HCL_IO_WRITE,
|
||||||
|
HCL_IO_WRITE_BYTES,
|
||||||
HCL_IO_FLUSH
|
HCL_IO_FLUSH
|
||||||
};
|
};
|
||||||
typedef enum hcl_iocmd_t hcl_iocmd_t;
|
typedef enum hcl_iocmd_t hcl_iocmd_t;
|
||||||
@ -1301,18 +1302,21 @@ struct hcl_iooutarg_t
|
|||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [IN] the pointer to the beginning of the character string
|
* [IN] the pointer to the beginning of the character/byte string
|
||||||
* to write
|
* to write.
|
||||||
|
* hcl_ooch_t* for HCL_IO_WRITE
|
||||||
|
* hcl_bch_t* or hcl_uint8_t* for HCL_IO_WRITE_BYTES
|
||||||
*/
|
*/
|
||||||
hcl_ooch_t* ptr;
|
void* ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [IN] total number of characters to write
|
* [IN] total number of characters/bytes to write
|
||||||
*/
|
*/
|
||||||
hcl_oow_t len;
|
hcl_oow_t len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [OUT] place the number of characters written here for HCL_IO_WRITE
|
* [OUT] place the number of characters/bytes written here for
|
||||||
|
* HCL_IO_WRITE or HCL_IO_WRITE_BYTES
|
||||||
*/
|
*/
|
||||||
hcl_oow_t xlen;
|
hcl_oow_t xlen;
|
||||||
};
|
};
|
||||||
@ -1696,7 +1700,7 @@ struct hcl_t
|
|||||||
} lit;
|
} lit;
|
||||||
|
|
||||||
/* the cumulative number of temporaries collected at the global(top-level) level */
|
/* the cumulative number of temporaries collected at the global(top-level) level */
|
||||||
hcl_oow_t ngtmprs;
|
hcl_oow_t ngtmprs;
|
||||||
|
|
||||||
/* array that holds the location of the byte code emitted */
|
/* array that holds the location of the byte code emitted */
|
||||||
hcl_dbgi_t* dbgi;
|
hcl_dbgi_t* dbgi;
|
||||||
@ -1778,8 +1782,8 @@ struct hcl_t
|
|||||||
#define HCL_STACK_GETTOP(hcl) HCL_STACK_GET(hcl, (hcl)->sp)
|
#define HCL_STACK_GETTOP(hcl) HCL_STACK_GET(hcl, (hcl)->sp)
|
||||||
#define HCL_STACK_SETTOP(hcl,obj_) HCL_STACK_SET(hcl, (hcl)->sp, obj_)
|
#define HCL_STACK_SETTOP(hcl,obj_) HCL_STACK_SET(hcl, (hcl)->sp, obj_)
|
||||||
|
|
||||||
/* [NOTE]
|
/* [NOTE]
|
||||||
* the following macros don't commit the active stack pointer(hcl->sp)
|
* the following macros don't commit the active stack pointer(hcl->sp)
|
||||||
* to hcl->processor->active->sp immediately.
|
* to hcl->processor->active->sp immediately.
|
||||||
*/
|
*/
|
||||||
#define HCL_STACK_POP(hcl) ((hcl)->sp = (hcl)->sp - 1)
|
#define HCL_STACK_POP(hcl) ((hcl)->sp = (hcl)->sp - 1)
|
||||||
@ -1806,7 +1810,7 @@ struct hcl_t
|
|||||||
/* change the receiver of a message */
|
/* change the receiver of a message */
|
||||||
#define HCL_STACK_SETRCV(hcl,nargs,newrcv) HCL_STACK_SET(hcl, (hcl)->sp - nargs - 1, newrcv)
|
#define HCL_STACK_SETRCV(hcl,nargs,newrcv) HCL_STACK_SET(hcl, (hcl)->sp - nargs - 1, newrcv)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* .....
|
* .....
|
||||||
* argument 1
|
* argument 1
|
||||||
* argument 0
|
* argument 0
|
||||||
@ -1904,7 +1908,7 @@ enum hcl_syncode_t
|
|||||||
HCL_SYNCODE_TRY,
|
HCL_SYNCODE_TRY,
|
||||||
HCL_SYNCODE_UNTIL,
|
HCL_SYNCODE_UNTIL,
|
||||||
HCL_SYNCODE_WHILE
|
HCL_SYNCODE_WHILE
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef enum hcl_syncode_t hcl_syncode_t;
|
typedef enum hcl_syncode_t hcl_syncode_t;
|
||||||
|
|
||||||
|
26
lib/std.c
26
lib/std.c
@ -3562,10 +3562,12 @@ static HCL_INLINE int close_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
|||||||
static HCL_INLINE int write_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
static HCL_INLINE int write_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
||||||
{
|
{
|
||||||
/*xtn_t* xtn = GET_XTN(hcl);*/
|
/*xtn_t* xtn = GET_XTN(hcl);*/
|
||||||
|
const hcl_ooch_t* ptr;
|
||||||
hcl_bch_t bcsbuf[1024];
|
hcl_bch_t bcsbuf[1024];
|
||||||
hcl_oow_t bcslen, ucslen, donelen;
|
hcl_oow_t bcslen, ucslen, donelen;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
ptr = (const hcl_ooch_t*)arg->ptr;
|
||||||
donelen = 0;
|
donelen = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -3573,14 +3575,14 @@ static HCL_INLINE int write_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
|||||||
#if defined(HCL_OOCH_IS_UCH)
|
#if defined(HCL_OOCH_IS_UCH)
|
||||||
bcslen = HCL_COUNTOF(bcsbuf);
|
bcslen = HCL_COUNTOF(bcsbuf);
|
||||||
ucslen = arg->len - donelen;
|
ucslen = arg->len - donelen;
|
||||||
x = hcl_convootobchars(hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen);
|
x = hcl_convootobchars(hcl, &ptr[donelen], &ucslen, bcsbuf, &bcslen);
|
||||||
if (x <= -1 && ucslen <= 0) return -1;
|
if (x <= -1 && ucslen <= 0) return -1;
|
||||||
#else
|
#else
|
||||||
bcslen = HCL_COUNTOF(bcsbuf);
|
bcslen = HCL_COUNTOF(bcsbuf);
|
||||||
ucslen = arg->len - donelen;
|
ucslen = arg->len - donelen;
|
||||||
if (ucslen > bcslen) ucslen = bcslen;
|
if (ucslen > bcslen) ucslen = bcslen;
|
||||||
else if (ucslen < bcslen) bcslen = ucslen;
|
else if (ucslen < bcslen) bcslen = ucslen;
|
||||||
hcl_copy_bchars (bcsbuf, &arg->ptr[donelen], bcslen);
|
hcl_copy_bchars (bcsbuf, &ptr[donelen], bcslen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fwrite(bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen)
|
if (fwrite(bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen)
|
||||||
@ -3597,6 +3599,23 @@ static HCL_INLINE int write_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HCL_INLINE int write_bytes_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
||||||
|
{
|
||||||
|
/*xtn_t* xtn = GET_XTN(hcl);*/
|
||||||
|
const hcl_uint8_t* ptr;
|
||||||
|
|
||||||
|
ptr = (const hcl_uint8_t*)arg->ptr; // take the buffer as a byte series
|
||||||
|
|
||||||
|
if (fwrite(ptr, HCL_SIZEOF(*ptr), arg->len, (FILE*)arg->handle) < arg->len)
|
||||||
|
{
|
||||||
|
hcl_seterrnum (hcl, HCL_EIOERR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg->xlen = arg->len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static HCL_INLINE int flush_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
static HCL_INLINE int flush_out_stream (hcl_t* hcl, hcl_iooutarg_t* arg)
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
@ -3621,6 +3640,9 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
|||||||
case HCL_IO_WRITE:
|
case HCL_IO_WRITE:
|
||||||
return write_out_stream(hcl, (hcl_iooutarg_t*)arg);
|
return write_out_stream(hcl, (hcl_iooutarg_t*)arg);
|
||||||
|
|
||||||
|
case HCL_IO_WRITE_BYTES:
|
||||||
|
return write_bytes_out_stream(hcl, (hcl_iooutarg_t*)arg);
|
||||||
|
|
||||||
case HCL_IO_FLUSH:
|
case HCL_IO_FLUSH:
|
||||||
return flush_out_stream(hcl, (hcl_iooutarg_t*)arg);
|
return flush_out_stream(hcl, (hcl_iooutarg_t*)arg);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user