put the hcl server code into a library
This commit is contained in:
parent
773f09aab2
commit
39749ab847
@ -648,7 +648,6 @@ typedef hcl_ooi_t (*hcl_outbfmt_t) (
|
||||
...
|
||||
);
|
||||
|
||||
|
||||
/* i don't want an error raised inside the callback to override
|
||||
* the existing error number and message. */
|
||||
#define vmprim_log_write(hcl,mask,ptr,len) do { \
|
||||
|
478
lib/hcl-s.c
478
lib/hcl-s.c
@ -146,17 +146,20 @@ struct bb_t
|
||||
hcl_bch_t* fn;
|
||||
};
|
||||
|
||||
typedef struct xtn_t xtn_t;
|
||||
struct xtn_t
|
||||
typedef struct worker_hcl_xtn_t worker_hcl_xtn_t;
|
||||
struct worker_hcl_xtn_t
|
||||
{
|
||||
hcl_server_proto_t* proto;
|
||||
int vm_running;
|
||||
|
||||
int logfd;
|
||||
unsigned int logmask;
|
||||
int logfd_istty;
|
||||
};
|
||||
|
||||
typedef struct dummy_hcl_xtn_t dummy_hcl_xtn_t;
|
||||
struct dummy_hcl_xtn_t
|
||||
{
|
||||
hcl_server_t* server;
|
||||
};
|
||||
|
||||
|
||||
enum hcl_server_proto_token_type_t
|
||||
{
|
||||
HCL_SERVER_PROTO_TOKEN_EOF,
|
||||
@ -173,7 +176,6 @@ enum hcl_server_proto_token_type_t
|
||||
|
||||
HCL_SERVER_PROTO_TOKEN_IDENT
|
||||
};
|
||||
|
||||
typedef enum hcl_server_proto_token_type_t hcl_server_proto_token_type_t;
|
||||
|
||||
typedef struct hcl_server_proto_token_t hcl_server_proto_token_t;
|
||||
@ -251,22 +253,25 @@ struct hcl_server_t
|
||||
{
|
||||
hcl_mmgr_t* mmgr;
|
||||
hcl_cmgr_t* cmgr;
|
||||
hcl_server_prim_t prim;
|
||||
hcl_t* dummy_hcl;
|
||||
|
||||
hcl_errnum_t errnum;
|
||||
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
hcl_ooch_t ooch[2048];
|
||||
hcl_bch_t bch[2048];
|
||||
hcl_uch_t uch[2048];
|
||||
} tmpbuf;
|
||||
hcl_ooch_t buf[2048];
|
||||
hcl_oow_t len;
|
||||
} errmsg;
|
||||
int stopreq;
|
||||
|
||||
int logfd;
|
||||
int logfd_istty;
|
||||
|
||||
struct
|
||||
{
|
||||
hcl_oow_t memsize; /* hcl heap memory size */
|
||||
unsigned int dbgopt;
|
||||
|
||||
unsigned int idle_timeout; /* idle timeout */
|
||||
|
||||
|
||||
unsigned int trait;
|
||||
unsigned int logmask;
|
||||
hcl_oow_t worker_stack_size;
|
||||
@ -288,31 +293,6 @@ int hcl_server_proto_feed_reply (hcl_server_proto_t* proto, const hcl_ooch_t* pt
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
|
||||
{
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
static hcl_mmgr_t sys_mmgr =
|
||||
{
|
||||
sys_alloc,
|
||||
sys_realloc,
|
||||
sys_free,
|
||||
HCL_NULL
|
||||
};
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
||||
# define IS_PATH_SEP(c) ((c) == '/' || (c) == '\\')
|
||||
@ -334,7 +314,7 @@ static const hcl_bch_t* get_base_name (const hcl_bch_t* path)
|
||||
|
||||
static HCL_INLINE int open_input (hcl_t* hcl, hcl_ioinarg_t* arg)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
bb_t* bb = HCL_NULL;
|
||||
|
||||
/* TOOD: support predefined include directory as well */
|
||||
@ -400,7 +380,7 @@ oops:
|
||||
|
||||
static HCL_INLINE int close_input (hcl_t* hcl, hcl_ioinarg_t* arg)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
bb_t* bb;
|
||||
|
||||
bb = (bb_t*)arg->handle;
|
||||
@ -416,7 +396,7 @@ static HCL_INLINE int close_input (hcl_t* hcl, hcl_ioinarg_t* arg)
|
||||
|
||||
static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
bb_t* bb;
|
||||
hcl_oow_t bcslen, ucslen, remlen;
|
||||
int x;
|
||||
@ -530,7 +510,7 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
|
||||
|
||||
case HCL_IO_WRITE:
|
||||
{
|
||||
xtn_t* xtn = (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;
|
||||
|
||||
if (hcl_server_proto_feed_reply(xtn->proto, outarg->ptr, outarg->len, 0) <= -1)
|
||||
@ -615,168 +595,26 @@ static void free_heap (hcl_t* hcl, void* ptr)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int write_all (int fd, const char* ptr, hcl_oow_t len)
|
||||
static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
hcl_ooi_t wr;
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
hcl_server_t* server;
|
||||
|
||||
wr = write (fd, ptr, len);
|
||||
|
||||
if (wr <= -1)
|
||||
{
|
||||
#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK)
|
||||
if (errno == EAGAIN) continue;
|
||||
#else
|
||||
# if defined(EAGAIN)
|
||||
if (errno == EAGAIN) continue;
|
||||
#elif defined(EWOULDBLOCK)
|
||||
if (errno == EWOULDBLOCK) continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EINTR)
|
||||
/* TODO: would this interfere with non-blocking nature of this VM? */
|
||||
if (errno == EINTR) continue;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr += wr;
|
||||
len -= wr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
server = xtn->proto->worker->server;
|
||||
pthread_mutex_lock (&server->log_mutex);
|
||||
server->prim.log_write (server, xtn->proto->worker->sck, mask, msg, len);
|
||||
pthread_mutex_unlock (&server->log_mutex);
|
||||
}
|
||||
|
||||
static void __log_write (hcl_server_t* server, int mask, const void* vmsg, hcl_oow_t len, int force_bch)
|
||||
static void log_write_for_dummy (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
{
|
||||
hcl_bch_t buf[256];
|
||||
hcl_oow_t ucslen, bcslen;
|
||||
int n;
|
||||
dummy_hcl_xtn_t* xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
hcl_server_t* server;
|
||||
|
||||
int logfd;
|
||||
|
||||
if (mask & HCL_LOG_STDERR)
|
||||
{
|
||||
/* the messages that go to STDERR don't get masked out */
|
||||
logfd = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(server->cfg.logmask & mask & ~HCL_LOG_ALL_LEVELS)) return; /* check log types */
|
||||
if (!(server->cfg.logmask & mask & ~HCL_LOG_ALL_TYPES)) return; /* check log levels */
|
||||
|
||||
if (mask & HCL_LOG_STDOUT) logfd = 1;
|
||||
else
|
||||
{
|
||||
logfd = server->logfd;
|
||||
if (logfd <= -1) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: beautify the log message.
|
||||
* do classification based on mask. */
|
||||
if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR)))
|
||||
{
|
||||
time_t now;
|
||||
char ts[32];
|
||||
size_t tslen;
|
||||
struct tm tm, *tmp;
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
tmp = localtime_r (&now, &tm);
|
||||
#if defined(HAVE_STRFTIME_SMALL_Z)
|
||||
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
|
||||
#else
|
||||
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp);
|
||||
#endif
|
||||
if (tslen == 0)
|
||||
{
|
||||
strcpy (ts, "0000-00-00 00:00:00 +0000");
|
||||
tslen = 25;
|
||||
}
|
||||
|
||||
/* TODO: less write system calls by having a buffer */
|
||||
write_all (logfd, ts, tslen);
|
||||
|
||||
/*
|
||||
* TODO: print IDs
|
||||
//tslen = snprintf (ts, sizeof(ts), "[%d] ", xtn->proto->worker->sck);
|
||||
//write_all (logfd, ts, tslen);
|
||||
*/
|
||||
}
|
||||
|
||||
if (server->logfd_istty)
|
||||
{
|
||||
if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7);
|
||||
else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7);
|
||||
else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7);
|
||||
}
|
||||
|
||||
#if defined(HCL_OOCH_IS_UCH)
|
||||
if (force_bch)
|
||||
{
|
||||
const hcl_bch_t* msg = (const hcl_bch_t*)vmsg;
|
||||
write_all (logfd, msg, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcl_oow_t msgidx;
|
||||
const hcl_ooch_t* msg = (const hcl_ooch_t*)vmsg;
|
||||
|
||||
msgidx = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
ucslen = len;
|
||||
bcslen = HCL_COUNTOF(buf);
|
||||
|
||||
n = hcl_conv_oocsn_to_bcsn_with_cmgr(&msg[msgidx], &ucslen, buf, &bcslen, hcl_get_utf8_cmgr());
|
||||
if (n == 0 || n == -2)
|
||||
{
|
||||
/* n = 0:
|
||||
* converted all successfully
|
||||
* n == -2:
|
||||
* buffer not sufficient. not all got converted yet.
|
||||
* write what have been converted this round. */
|
||||
|
||||
/*HCL_ASSERT (hcl, ucslen > 0); */ /* if this fails, the buffer size must be increased */
|
||||
assert (ucslen > 0);
|
||||
|
||||
/* attempt to write all converted characters */
|
||||
if (write_all(logfd, buf, bcslen) <= -1) break;
|
||||
|
||||
if (n == 0) break;
|
||||
else
|
||||
{
|
||||
msgidx += ucslen;
|
||||
len -= ucslen;
|
||||
}
|
||||
}
|
||||
else if (n <= -1)
|
||||
{
|
||||
/* conversion error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
write_all (logfd, vmsg, len);
|
||||
#endif
|
||||
|
||||
if (server->logfd_istty)
|
||||
{
|
||||
if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
pthread_mutex_lock (&xtn->proto->worker->server->log_mutex);
|
||||
__log_write (xtn->proto->worker->server, mask, msg, len, 0);
|
||||
pthread_mutex_unlock (&xtn->proto->worker->server->log_mutex);
|
||||
server = xtn->server;
|
||||
pthread_mutex_lock (&server->log_mutex);
|
||||
server->prim.log_write (server, -1, mask, msg, len);
|
||||
pthread_mutex_unlock (&server->log_mutex);
|
||||
}
|
||||
|
||||
static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len)
|
||||
@ -1057,20 +895,20 @@ static void vm_sleep (hcl_t* hcl, const hcl_ntime_t* dur)
|
||||
|
||||
static int vm_startup (hcl_t* hcl)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
xtn->vm_running = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vm_cleanup (hcl_t* hcl)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
xtn->vm_running = 0;
|
||||
}
|
||||
|
||||
static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
|
||||
if (xtn->proto->worker->server->stopreq) hcl_abort(hcl);
|
||||
/* TODO: check how to this vm has been running. too long? abort it */
|
||||
@ -1082,11 +920,11 @@ static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode)
|
||||
static void gc_hcl (hcl_t* hcl)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static void fini_hcl (hcl_t* hcl)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
if (xtn->logfd >= 0)
|
||||
{
|
||||
close (xtn->logfd);
|
||||
@ -1094,7 +932,7 @@ static void fini_hcl (hcl_t* hcl)
|
||||
xtn->logfd_istty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/* ========================================================================= */
|
||||
|
||||
#define HCL_SERVER_PROTO_LOG_MASK (HCL_LOG_ERROR | HCL_LOG_APP)
|
||||
@ -1104,7 +942,7 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
|
||||
hcl_server_proto_t* proto;
|
||||
hcl_vmprim_t vmprim;
|
||||
hcl_cb_t hclcb;
|
||||
xtn_t* xtn;
|
||||
worker_hcl_xtn_t* xtn;
|
||||
unsigned int trait;
|
||||
|
||||
HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim));
|
||||
@ -1121,29 +959,31 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
|
||||
vmprim.vm_gettime = vm_gettime;
|
||||
vmprim.vm_sleep = vm_sleep;
|
||||
|
||||
proto = (hcl_server_proto_t*)malloc(sizeof(*proto));
|
||||
if (!proto) return NULL;
|
||||
proto = (hcl_server_proto_t*)HCL_MMGR_ALLOC(worker->server->mmgr, HCL_SIZEOF(*proto));
|
||||
if (!proto) return HCL_NULL;
|
||||
|
||||
HCL_MEMSET (proto, 0, sizeof(*proto));
|
||||
HCL_MEMSET (proto, 0, HCL_SIZEOF(*proto));
|
||||
proto->worker = worker;
|
||||
|
||||
proto->hcl = hcl_open(&sys_mmgr, HCL_SIZEOF(xtn_t), worker->server->cfg.actor_heap_size, &vmprim, HCL_NULL);
|
||||
proto->hcl = hcl_open(proto->worker->server->mmgr, HCL_SIZEOF(*xtn), worker->server->cfg.actor_heap_size, &vmprim, HCL_NULL);
|
||||
if (!proto->hcl) goto oops;
|
||||
|
||||
xtn = (xtn_t*)hcl_getxtn(proto->hcl);
|
||||
xtn->logfd = -1;
|
||||
xtn->logfd_istty = 0;
|
||||
xtn = (worker_hcl_xtn_t*)hcl_getxtn(proto->hcl);
|
||||
xtn->proto = proto;
|
||||
|
||||
hcl_setcmgr (proto->hcl, hcl_get_utf8_cmgr());
|
||||
hcl_setoption (proto->hcl, HCL_LOG_MASK, &proto->worker->server->cfg.logmask);
|
||||
hcl_setcmgr (proto->hcl, proto->worker->server->cmgr);
|
||||
|
||||
hcl_getoption (proto->hcl, HCL_TRAIT, &trait);
|
||||
trait |= proto->worker->server->cfg.dbgopt;
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC;
|
||||
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
|
||||
#endif
|
||||
hcl_setoption (proto->hcl, HCL_TRAIT, &trait);
|
||||
|
||||
HCL_MEMSET (&hclcb, 0, HCL_SIZEOF(hclcb));
|
||||
hclcb.fini = fini_hcl;
|
||||
/*hclcb.gc = gc_hcl;*/
|
||||
/*hclcb.fini = fini_hcl;
|
||||
hclcb.gc = gc_hcl;*/
|
||||
hclcb.vm_startup = vm_startup;
|
||||
hclcb.vm_cleanup = vm_cleanup;
|
||||
hclcb.vm_checkbc = vm_checkbc;
|
||||
@ -1159,16 +999,16 @@ oops:
|
||||
if (proto)
|
||||
{
|
||||
if (proto->hcl) hcl_close (proto->hcl);
|
||||
free (proto);
|
||||
HCL_MMGR_FREE (proto->worker->server->mmgr, proto);
|
||||
}
|
||||
return NULL;
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
void hcl_server_proto_close (hcl_server_proto_t* proto)
|
||||
{
|
||||
if (proto->tok.ptr) free (proto->tok.ptr);
|
||||
if (proto->tok.ptr) HCL_MMGR_FREE (proto->worker->server->mmgr, proto->tok.ptr);
|
||||
hcl_close (proto->hcl);
|
||||
free (proto);
|
||||
HCL_MMGR_FREE (proto->worker->server->mmgr, proto);
|
||||
}
|
||||
|
||||
static int write_reply_chunk (hcl_server_proto_t* proto)
|
||||
@ -1188,7 +1028,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
|
||||
}
|
||||
|
||||
iov[count].iov_base = cl,
|
||||
iov[count++].iov_len = snprintf(cl, sizeof(cl), "%s%zu:", (((proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_READABLE_PROTO) && proto->reply.nchunks > 0)? "\n": ""), proto->reply.len);
|
||||
iov[count++].iov_len = snprintf(cl, HCL_SIZEOF(cl), "%s%zu:", (((proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_READABLE_PROTO) && proto->reply.nchunks > 0)? "\n": ""), proto->reply.len);
|
||||
}
|
||||
iov[count].iov_base = proto->reply.buf;
|
||||
iov[count++].iov_len = proto->reply.len;
|
||||
@ -1197,7 +1037,7 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
|
||||
HCL_MEMSET (&msg, 0, sizeof(msg));
|
||||
HCL_MEMSET (&msg, 0, HCL_SIZEOF(msg));
|
||||
msg.msg_iov = (struct iovec*)&iov[index];
|
||||
msg.msg_iovlen = count - index;
|
||||
nwritten = sendmsg(proto->worker->sck, &msg, 0);
|
||||
@ -1400,7 +1240,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c)
|
||||
hcl_oow_t capa;
|
||||
|
||||
capa = HCL_ALIGN_POW2(proto->tok.len + 1, 64);
|
||||
tmp = (hcl_ooch_t*)realloc(proto->tok.ptr, capa * sizeof(*tmp));
|
||||
tmp = (hcl_ooch_t*)HCL_MMGR_REALLOC(proto->worker->server->mmgr, proto->tok.ptr, capa * HCL_SIZEOF(*tmp));
|
||||
if (!tmp)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "out of memory in allocating a token buffer\n");
|
||||
@ -1538,7 +1378,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
}
|
||||
|
||||
hcl_server_proto_start_reply (proto);
|
||||
if (hcl_server_proto_end_reply(proto, NULL) <= -1)
|
||||
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .EXIT\n");
|
||||
return -1;
|
||||
@ -1582,7 +1422,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
|
||||
hcl_server_proto_start_reply (proto);
|
||||
obj = (hcl_getbclen(proto->hcl) > 0)? hcl_execute(proto->hcl): proto->hcl->_nil;
|
||||
if (hcl_server_proto_end_reply(proto, (obj? NULL: hcl_geterrmsg(proto->hcl))) <= -1)
|
||||
if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .END\n");
|
||||
return -1;
|
||||
@ -1622,7 +1462,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
{
|
||||
hcl_server_proto_start_reply (proto);
|
||||
obj = hcl_execute(proto->hcl);
|
||||
if (hcl_server_proto_end_reply(proto, (obj? NULL: hcl_geterrmsg(proto->hcl))) <= -1)
|
||||
if (hcl_server_proto_end_reply(proto, (obj? HCL_NULL: hcl_geterrmsg(proto->hcl))) <= -1)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .SCRIPT\n");
|
||||
return -1;
|
||||
@ -1639,7 +1479,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
//print_hcl_server_workers (proto);
|
||||
pthread_mutex_unlock (&proto->worker->server->worker_mutex);
|
||||
|
||||
if (hcl_server_proto_end_reply(proto, NULL) <= -1)
|
||||
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .SHOW-WORKERS\n");
|
||||
return -1;
|
||||
@ -1654,7 +1494,7 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
//kill_hcl_server_worker (proto);
|
||||
pthread_mutex_unlock (&proto->worker->server->worker_mutex);
|
||||
|
||||
if (hcl_server_proto_end_reply(proto, NULL) <= -1)
|
||||
if (hcl_server_proto_end_reply(proto, HCL_NULL) <= -1)
|
||||
{
|
||||
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "cannot finalize reply for .KILL-WORKER\n");
|
||||
return -1;
|
||||
@ -1671,46 +1511,73 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, unsigned int dbgopt)
|
||||
hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_prim_t* prim, hcl_errnum_t* errnum)
|
||||
{
|
||||
hcl_server_t* server;
|
||||
hcl_t* hcl;
|
||||
hcl_vmprim_t vmprim;
|
||||
dummy_hcl_xtn_t* xtn;
|
||||
|
||||
server = (hcl_server_t*)malloc(sizeof(*server) + xtnsize);
|
||||
if (!server) return NULL;
|
||||
server = (hcl_server_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*server) + xtnsize);
|
||||
if (!server)
|
||||
{
|
||||
if (errnum) *errnum = HCL_ESYSMEM;
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
HCL_MEMSET (server, 0, sizeof(*server) + xtnsize);
|
||||
HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim));
|
||||
vmprim.log_write = log_write_for_dummy;
|
||||
vmprim.syserrstrb = syserrstrb;
|
||||
vmprim.dl_open = dl_open;
|
||||
vmprim.dl_close = dl_close;
|
||||
vmprim.dl_getsym = dl_getsym;
|
||||
vmprim.vm_gettime = vm_gettime;
|
||||
vmprim.vm_sleep = vm_sleep;
|
||||
|
||||
server->logfd = -1;
|
||||
server->logfd_istty = 0;
|
||||
hcl = hcl_open(mmgr, HCL_SIZEOF(*xtn), 10240, &vmprim, errnum);
|
||||
if (!hcl)
|
||||
{
|
||||
HCL_MMGR_FREE (mmgr, server);
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
server->cfg.dbgopt = dbgopt;
|
||||
server->cfg.trait = HCL_SERVER_TRAIT_READABLE_PROTO | HCL_SERVER_TRAIT_USE_LARGE_PAGES; /* TODO: make it configurable */
|
||||
xtn = (dummy_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
xtn->server = server;
|
||||
|
||||
HCL_MEMSET (server, 0, HCL_SIZEOF(*server) + xtnsize);
|
||||
server->mmgr = mmgr;
|
||||
server->cmgr = hcl_get_utf8_cmgr();
|
||||
server->prim = *prim;
|
||||
server->dummy_hcl = hcl;
|
||||
|
||||
server->cfg.logmask = ~0u;
|
||||
server->cfg.worker_stack_size = 512000UL;
|
||||
server->cfg.actor_heap_size = 512000UL;
|
||||
|
||||
pthread_mutex_init (&server->worker_mutex, NULL);
|
||||
pthread_mutex_init (&server->log_mutex, NULL);
|
||||
pthread_mutex_init (&server->worker_mutex, HCL_NULL);
|
||||
pthread_mutex_init (&server->log_mutex, HCL_NULL);
|
||||
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
void hcl_server_close (hcl_server_t* server)
|
||||
{
|
||||
if (server->logfd >= 0) close (server->logfd);
|
||||
pthread_mutex_destroy (&server->log_mutex);
|
||||
pthread_mutex_destroy (&server->worker_mutex);
|
||||
free (server);
|
||||
|
||||
hcl_close (server->dummy_hcl);
|
||||
HCL_MMGR_FREE (server->mmgr, server);
|
||||
}
|
||||
|
||||
static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck)
|
||||
{
|
||||
hcl_server_worker_t* worker;
|
||||
|
||||
worker = (hcl_server_worker_t*)malloc(sizeof(*worker));
|
||||
if (!worker) return NULL;
|
||||
worker = (hcl_server_worker_t*)HCL_MMGR_ALLOC (server->mmgr, HCL_SIZEOF(*worker));
|
||||
if (!worker) return HCL_NULL;
|
||||
|
||||
HCL_MEMSET (worker, 0, sizeof(*worker));
|
||||
HCL_MEMSET (worker, 0, HCL_SIZEOF(*worker));
|
||||
worker->sck = cli_sck;
|
||||
worker->server = server;
|
||||
return worker;
|
||||
@ -1719,7 +1586,7 @@ static hcl_server_worker_t* alloc_worker (hcl_server_t* server, int cli_sck)
|
||||
static void free_worker (hcl_server_worker_t* worker)
|
||||
{
|
||||
if (worker->sck >= 0) close (worker->sck);
|
||||
free (worker);
|
||||
HCL_MMGR_FREE (worker->server->mmgr, worker);
|
||||
}
|
||||
|
||||
static void add_hcl_server_worker_to_server (hcl_server_t* server, hcl_server_worker_state_t wstate, hcl_server_worker_t* worker)
|
||||
@ -1731,14 +1598,14 @@ static void add_hcl_server_worker_to_server (hcl_server_t* server, hcl_server_wo
|
||||
server->worker_list[wstate].tail->next_worker = worker;
|
||||
worker->prev_worker = server->worker_list[wstate].tail;
|
||||
server->worker_list[wstate].tail = worker;
|
||||
worker->next_worker = NULL;
|
||||
worker->next_worker = HCL_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
server->worker_list[wstate].tail = worker;
|
||||
server->worker_list[wstate].head = worker;
|
||||
worker->prev_worker = NULL;
|
||||
worker->next_worker = NULL;
|
||||
worker->prev_worker = HCL_NULL;
|
||||
worker->next_worker = HCL_NULL;
|
||||
}
|
||||
|
||||
worker->state = wstate;
|
||||
@ -1756,8 +1623,8 @@ static void zap_worker_in_server (hcl_server_t* server, hcl_server_worker_t* wor
|
||||
if (worker->next_worker) worker->next_worker->prev_worker = worker->prev_worker;
|
||||
else server->worker_list[wstate].tail = worker->prev_worker;
|
||||
|
||||
worker->prev_worker = NULL;
|
||||
worker->next_worker = NULL;
|
||||
worker->prev_worker = HCL_NULL;
|
||||
worker->next_worker = HCL_NULL;
|
||||
}
|
||||
|
||||
static void* worker_main (void* ctx)
|
||||
@ -1767,14 +1634,14 @@ static void* worker_main (void* ctx)
|
||||
sigset_t set;
|
||||
|
||||
sigfillset (&set);
|
||||
pthread_sigmask (SIG_BLOCK, &set, NULL);
|
||||
pthread_sigmask (SIG_BLOCK, &set, HCL_NULL);
|
||||
|
||||
worker->thr = pthread_self();
|
||||
worker->proto = hcl_server_proto_open(0, worker); /* TODO: get this from argumen */
|
||||
if (!worker->proto)
|
||||
{
|
||||
free_worker (worker);
|
||||
return NULL;
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock (&server->worker_mutex);
|
||||
@ -1787,7 +1654,7 @@ static void* worker_main (void* ctx)
|
||||
}
|
||||
|
||||
hcl_server_proto_close (worker->proto);
|
||||
worker->proto = NULL;
|
||||
worker->proto = HCL_NULL;
|
||||
|
||||
pthread_mutex_lock (&server->worker_mutex);
|
||||
|
||||
@ -1802,7 +1669,7 @@ static void* worker_main (void* ctx)
|
||||
}
|
||||
pthread_mutex_unlock (&server->worker_mutex);
|
||||
|
||||
return NULL;
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
static void purge_all_workers (hcl_server_t* server, hcl_server_worker_state_t wstate)
|
||||
@ -1823,26 +1690,25 @@ static void purge_all_workers (hcl_server_t* server, hcl_server_worker_state_t w
|
||||
pthread_mutex_unlock (&server->worker_mutex);
|
||||
if (!worker) break;
|
||||
|
||||
pthread_join (worker->thr, NULL);
|
||||
pthread_join (worker->thr, HCL_NULL);
|
||||
free_worker (worker);
|
||||
}
|
||||
}
|
||||
|
||||
static void hcl_server_write_log (hcl_server_t* server, int mask, const char* fmt, ...)
|
||||
void hcl_server_logbfmt (hcl_server_t* server, unsigned int mask, const hcl_bch_t* fmt, ...)
|
||||
{
|
||||
char esbuf[256];
|
||||
int eslen;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
eslen = vsnprintf (esbuf, HCL_COUNTOF(esbuf), fmt, ap);
|
||||
hcl_logbfmtv (server->dummy_hcl, mask, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
if (eslen >= HCL_COUNTOF(esbuf)) eslen = HCL_COUNTOF(esbuf) - 1;
|
||||
|
||||
pthread_mutex_lock (&server->log_mutex);
|
||||
__log_write (server, mask, esbuf, eslen, 1);
|
||||
pthread_mutex_unlock (&server->log_mutex);
|
||||
void hcl_server_logufmt (hcl_server_t* server, unsigned int mask, const hcl_uch_t* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
hcl_logufmtv (server->dummy_hcl, mask, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
int hcl_server_start (hcl_server_t* server, const char* addrs)
|
||||
@ -1856,7 +1722,7 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
|
||||
/* TODO: interprete 'addrs' as a command-separated address list
|
||||
* 192.168.1.1:20,[::1]:20,127.0.0.1:345
|
||||
*/
|
||||
HCL_MEMSET (&srv_addr, 0, sizeof(srv_addr));
|
||||
HCL_MEMSET (&srv_addr, 0, HCL_SIZEOF(srv_addr));
|
||||
if (inet_pton(AF_INET6, addrs, &srv_addr.in6.sin6_addr) != 1)
|
||||
{
|
||||
if (inet_pton(AF_INET, addrs, &srv_addr.in4.sin_addr) != 1)
|
||||
@ -1868,7 +1734,7 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
|
||||
{
|
||||
srv_addr.in4.sin_family = AF_INET;
|
||||
srv_addr.in4.sin_port = htons(8888); /* TODO: change it */
|
||||
srv_len = sizeof(srv_addr.in4);
|
||||
srv_len = HCL_SIZEOF(srv_addr.in4);
|
||||
sck_fam = AF_INET;
|
||||
}
|
||||
}
|
||||
@ -1876,30 +1742,36 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
|
||||
{
|
||||
srv_addr.in6.sin6_family = AF_INET6;
|
||||
srv_addr.in6.sin6_port = htons(8888); /* TODO: change it */
|
||||
srv_len = sizeof(srv_addr.in6);
|
||||
srv_len = HCL_SIZEOF(srv_addr.in6);
|
||||
sck_fam = AF_INET6;
|
||||
}
|
||||
|
||||
srv_fd = socket(sck_fam, SOCK_STREAM, 0);
|
||||
if (srv_fd == -1)
|
||||
{
|
||||
hcl_server_write_log (server, HCL_SERVER_PROTO_LOG_MASK, "cannot open server socket - %s\n", strerror(errno));
|
||||
int xerrno = errno;
|
||||
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
|
||||
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot open server socket - %s\n", strerror(xerrno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt (srv_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
|
||||
setsockopt (srv_fd, SOL_SOCKET, SO_REUSEADDR, &optval, HCL_SIZEOF(int));
|
||||
|
||||
if (bind(srv_fd, (struct sockaddr*)&srv_addr, srv_len) == -1)
|
||||
{
|
||||
hcl_server_write_log (server, HCL_SERVER_PROTO_LOG_MASK, "cannot bind server socket %d - %s\n", srv_fd, strerror(errno));
|
||||
int xerrno = errno;
|
||||
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
|
||||
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot bind server socket %d - %s\n", srv_fd, strerror(xerrno));
|
||||
close (srv_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen (srv_fd, 128) == -1)
|
||||
{
|
||||
hcl_server_write_log (server, HCL_SERVER_PROTO_LOG_MASK, "cannot listen on server socket %d - %s\n", srv_fd, strerror(errno));
|
||||
int xerrno = errno;
|
||||
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
|
||||
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot listen on server socket %d - %s\n", srv_fd, strerror(xerrno));
|
||||
close (srv_fd);
|
||||
return -1;
|
||||
}
|
||||
@ -1919,19 +1791,20 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
|
||||
|
||||
purge_all_workers (server, HCL_SERVER_WORKER_STATE_DEAD);
|
||||
|
||||
cli_len = sizeof(cli_addr);
|
||||
cli_len = HCL_SIZEOF(cli_addr);
|
||||
cli_fd = accept(srv_fd, (struct sockaddr*)&cli_addr, &cli_len);
|
||||
if (cli_fd == -1)
|
||||
{
|
||||
if (errno != EINTR || !server->stopreq)
|
||||
{
|
||||
hcl_server_write_log (server, HCL_SERVER_PROTO_LOG_MASK, "cannot accept worker on socket %d - %s\n", srv_fd, strerror(errno));
|
||||
int xerrno = errno;
|
||||
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
|
||||
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot accept worker on socket %d - %s\n", srv_fd, strerror(xerrno));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
worker = alloc_worker(server, cli_fd);
|
||||
|
||||
if (pthread_create(&thr, &thr_attr, worker_main, worker) != 0)
|
||||
{
|
||||
free_worker (worker);
|
||||
@ -1969,10 +1842,10 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
||||
case HCL_SERVER_ACTOR_HEAP_SIZE:
|
||||
server->cfg.actor_heap_size = *(hcl_oow_t*)value;
|
||||
return 0;
|
||||
// TODO: add more options
|
||||
|
||||
}
|
||||
|
||||
//hcl_server_seterrnum (server, HCL_SERVER_EINVAL);
|
||||
hcl_server_seterrnum (server, HCL_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1997,6 +1870,49 @@ int hcl_server_getoption (hcl_server_t* server, hcl_server_option_t id, void* va
|
||||
return 0;
|
||||
};
|
||||
|
||||
//hcl_server_seterrnum (server, HCL_SERVER_EINVAL);
|
||||
hcl_server_seterrnum (server, HCL_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* hcl_server_getxtn (hcl_server_t* server)
|
||||
{
|
||||
return (void*)(server + 1);
|
||||
}
|
||||
|
||||
hcl_mmgr_t* hcl_server_getmmgr (hcl_server_t* server)
|
||||
{
|
||||
return server->mmgr;
|
||||
}
|
||||
|
||||
hcl_cmgr_t* hcl_server_getcmgr (hcl_server_t* server)
|
||||
{
|
||||
return server->cmgr;
|
||||
}
|
||||
|
||||
void hcl_server_setcmgr (hcl_server_t* server, hcl_cmgr_t* cmgr)
|
||||
{
|
||||
server->cmgr = cmgr;
|
||||
}
|
||||
|
||||
hcl_errnum_t hcl_server_geterrnum (hcl_server_t* server)
|
||||
{
|
||||
return server->errnum;
|
||||
}
|
||||
|
||||
const hcl_ooch_t* hcl_server_geterrstr (hcl_server_t* server)
|
||||
{
|
||||
return hcl_errnum_to_errstr(server->errnum);
|
||||
}
|
||||
|
||||
const hcl_ooch_t* hcl_server_geterrmsg (hcl_server_t* server)
|
||||
{
|
||||
if (server->errmsg.len <= 0) return hcl_errnum_to_errstr(server->errnum);
|
||||
return server->errmsg.buf;
|
||||
}
|
||||
|
||||
void hcl_server_seterrnum (hcl_server_t* server, hcl_errnum_t errnum)
|
||||
{
|
||||
/*if (server->shuterr) return; */
|
||||
server->errnum = errnum;
|
||||
server->errmsg.len = 0;
|
||||
}
|
||||
|
75
lib/hcl-s.h
75
lib/hcl-s.h
@ -44,12 +44,32 @@ typedef enum hcl_server_option_t hcl_server_option_t;
|
||||
|
||||
enum hcl_server_trait_t
|
||||
{
|
||||
HCL_SERVER_TRAIT_READABLE_PROTO = (1 << 0),
|
||||
HCL_SERVER_TRAIT_USE_LARGE_PAGES = (1 << 1)
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
HCL_SERVER_TRAIT_DEBUG_GC = (1 << 0),
|
||||
HCL_SERVER_TRAIT_DEBUG_BIGINT = (1 << 1),
|
||||
#endif
|
||||
|
||||
HCL_SERVER_TRAIT_READABLE_PROTO = (1 << 2),
|
||||
HCL_SERVER_TRAIT_USE_LARGE_PAGES = (1 << 3)
|
||||
};
|
||||
typedef enum hcl_server_trait_t hcl_server_trait_t;
|
||||
|
||||
|
||||
typedef void (*hcl_server_log_write_t) (
|
||||
hcl_server_t* server,
|
||||
int wid,
|
||||
unsigned int mask,
|
||||
const hcl_ooch_t* msg,
|
||||
hcl_oow_t len
|
||||
);
|
||||
|
||||
struct hcl_server_prim_t
|
||||
{
|
||||
hcl_server_log_write_t log_write;
|
||||
};
|
||||
typedef struct hcl_server_prim_t hcl_server_prim_t;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -57,14 +77,14 @@ extern "C" {
|
||||
HCL_EXPORT hcl_server_t* hcl_server_open (
|
||||
hcl_mmgr_t* mmgr,
|
||||
hcl_oow_t xtnsize,
|
||||
unsigned int dbgopt
|
||||
hcl_server_prim_t* prim,
|
||||
hcl_errnum_t* errnum
|
||||
);
|
||||
|
||||
HCL_EXPORT void hcl_server_close (
|
||||
hcl_server_t* server
|
||||
);
|
||||
|
||||
|
||||
HCL_EXPORT int hcl_server_start (
|
||||
hcl_server_t* server,
|
||||
const char* addrs
|
||||
@ -86,26 +106,47 @@ HCL_EXPORT int hcl_server_getoption (
|
||||
void* value
|
||||
);
|
||||
|
||||
HCL_EXPORT void* hcl_server_getxtn (
|
||||
hcl_server_t* server
|
||||
);
|
||||
|
||||
#if defined(HCL_HAVE_INLINE)
|
||||
static HCL_INLINE hcl_mmgr_t* hcl_server_getmmgr (hcl_server_t* server) { return server->mmgr; }
|
||||
static HCL_INLINE void* hcl_server_getxtn (hcl_server_t* server) { return (void*)(hcl + 1); }
|
||||
|
||||
/*static HCL_INLINE hcl_server_cmgr_t* hcl_server_getcmgr (hcl_server_t* server) { return server->cmgr; }
|
||||
static HCL_INLINE void hcl_server_setcmgr (hcl_server_t* hcl, hcl_server_cmgr_t* cmgr) { server->cmgr = cmgr; }*/
|
||||
HCL_EXPORT hcl_mmgr_t* hcl_server_getmmgr (
|
||||
hcl_server_t* server
|
||||
);
|
||||
|
||||
static HCL_INLINE hcl_server_errnum_t hcl_server_geterrnum (hcl_server_t* server) { return server->errnum; }
|
||||
|
||||
#else
|
||||
# define hcl_server_getmmgr(server) ((server)->mmgr)
|
||||
# define hcl_server_getxtn(server) ((void*)((server) + 1))
|
||||
HCL_EXPORT hcl_cmgr_t* hcl_server_getcmgr (
|
||||
hcl_server_t* server
|
||||
);
|
||||
|
||||
/*# define hcl_server_getcmgr(server) ((server)->cmgr)
|
||||
# define hcl_server_setcmgr(hcl,mgr) ((server)->cmgr = (mgr))*/
|
||||
HCL_EXPORT void hcl_server_setcmgr (
|
||||
hcl_server_t* server,
|
||||
hcl_cmgr_t* cmgr
|
||||
);
|
||||
|
||||
# define hcl_server_geterrnum(server) ((server)->errnum)
|
||||
#endif
|
||||
HCL_EXPORT hcl_errnum_t hcl_server_geterrnum (
|
||||
hcl_server_t* server
|
||||
);
|
||||
|
||||
HCL_EXPORT void hcl_server_seterrnum (
|
||||
hcl_server_t* server,
|
||||
hcl_errnum_t errnum
|
||||
);
|
||||
|
||||
HCL_EXPORT void hcl_server_logbfmt (
|
||||
hcl_server_t* server,
|
||||
unsigned int mask,
|
||||
const hcl_bch_t* fmt,
|
||||
...
|
||||
);
|
||||
|
||||
HCL_EXPORT void hcl_server_logufmt (
|
||||
hcl_server_t* server,
|
||||
unsigned int mask,
|
||||
const hcl_uch_t* fmt,
|
||||
...
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
66
lib/hcl.h
66
lib/hcl.h
@ -29,6 +29,7 @@
|
||||
|
||||
#include "hcl-cmn.h"
|
||||
#include "hcl-rbt.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* TODO: move this macro out to the build files.... */
|
||||
#define HCL_INCLUDE_COMPILER
|
||||
@ -692,7 +693,7 @@ struct hcl_heap_t
|
||||
typedef void* (*hcl_alloc_heap_t) (hcl_t* hcl, hcl_oow_t size);
|
||||
typedef void (*hcl_free_heap_t) (hcl_t* hcl, void* ptr);
|
||||
|
||||
typedef void (*hcl_log_write_t) (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len);
|
||||
typedef void (*hcl_log_write_t) (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len);
|
||||
typedef void (*hcl_syserrstrb_t) (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len);
|
||||
typedef void (*hcl_syserrstru_t) (hcl_t* hcl, int syserr, hcl_uch_t* buf, hcl_oow_t len);
|
||||
|
||||
@ -1214,29 +1215,33 @@ struct hcl_t
|
||||
|
||||
enum hcl_log_mask_t
|
||||
{
|
||||
HCL_LOG_DEBUG = (1 << 0),
|
||||
HCL_LOG_INFO = (1 << 1),
|
||||
HCL_LOG_WARN = (1 << 2),
|
||||
HCL_LOG_ERROR = (1 << 3),
|
||||
HCL_LOG_FATAL = (1 << 4),
|
||||
HCL_LOG_DEBUG = (1u << 0),
|
||||
HCL_LOG_INFO = (1u << 1),
|
||||
HCL_LOG_WARN = (1u << 2),
|
||||
HCL_LOG_ERROR = (1u << 3),
|
||||
HCL_LOG_FATAL = (1u << 4),
|
||||
|
||||
HCL_LOG_UNTYPED = (1 << 6), /* only to be used by HCL_DEBUGx() and HCL_INFOx() */
|
||||
HCL_LOG_COMPILER = (1 << 7),
|
||||
HCL_LOG_VM = (1 << 8),
|
||||
HCL_LOG_MNEMONIC = (1 << 9), /* bytecode mnemonic */
|
||||
HCL_LOG_GC = (1 << 10),
|
||||
HCL_LOG_IC = (1 << 11), /* instruction cycle, fetch-decode-execute */
|
||||
HCL_LOG_PRIMITIVE = (1 << 12),
|
||||
HCL_LOG_APP = (1 << 13), /* hcl applications, set by hcl logging primitive */
|
||||
HCL_LOG_UNTYPED = (1u << 6), /* only to be used by HCL_DEBUGx() and HCL_INFOx() */
|
||||
HCL_LOG_COMPILER = (1u << 7),
|
||||
HCL_LOG_VM = (1u << 8),
|
||||
HCL_LOG_MNEMONIC = (1u << 9), /* bytecode mnemonic */
|
||||
HCL_LOG_GC = (1u << 10),
|
||||
HCL_LOG_IC = (1u << 11), /* instruction cycle, fetch-decode-execute */
|
||||
HCL_LOG_PRIMITIVE = (1u << 12),
|
||||
|
||||
HCL_LOG_APP = (1u << 13), /* hcl applications, set by hcl logging primitive */
|
||||
HCL_LOG_APP_X1 = (1u << 14), /* more hcl applications, you can choose to use one of APP_X? randomly */
|
||||
HCL_LOG_APP_X2 = (1u << 15),
|
||||
HCL_LOG_APP_X3 = (1u << 16),
|
||||
|
||||
HCL_LOG_ALL_LEVELS = (HCL_LOG_DEBUG | HCL_LOG_INFO | HCL_LOG_WARN | HCL_LOG_ERROR | HCL_LOG_FATAL),
|
||||
HCL_LOG_ALL_TYPES = (HCL_LOG_UNTYPED | HCL_LOG_COMPILER | HCL_LOG_VM | HCL_LOG_MNEMONIC | HCL_LOG_GC | HCL_LOG_IC | HCL_LOG_PRIMITIVE | HCL_LOG_APP),
|
||||
HCL_LOG_ALL_TYPES = (HCL_LOG_UNTYPED | HCL_LOG_COMPILER | HCL_LOG_VM | HCL_LOG_MNEMONIC | HCL_LOG_GC | HCL_LOG_IC | HCL_LOG_PRIMITIVE | HCL_LOG_APP | HCL_LOG_APP_X1 | HCL_LOG_APP_X2 | HCL_LOG_APP_X3),
|
||||
|
||||
|
||||
HCL_LOG_STDOUT = (1 << 14), /* write log messages to stdout without timestamp. HCL_LOG_STDOUT wins over HCL_LOG_STDERR. */
|
||||
HCL_LOG_STDERR = (1 << 15), /* write log messages to stderr without timestamp. */
|
||||
HCL_LOG_STDOUT = (1u << 20), /* write log messages to stdout without timestamp. HCL_LOG_STDOUT wins over HCL_LOG_STDERR. */
|
||||
HCL_LOG_STDERR = (1u << 21), /* write log messages to stderr without timestamp. */
|
||||
|
||||
HCL_LOG_PREFER_JSON = (1 << 30) /* write a object in the json format. don't set this explicitly. use %J instead */
|
||||
HCL_LOG_PREFER_JSON = (1u << 30) /* write a object in the json format. don't set this explicitly. use %J instead */
|
||||
};
|
||||
typedef enum hcl_log_mask_t hcl_log_mask_t;
|
||||
|
||||
@ -1478,6 +1483,14 @@ HCL_EXPORT const hcl_ooch_t* hcl_backuperrmsg (
|
||||
hcl_t* hcl
|
||||
);
|
||||
|
||||
HCL_EXPORT const hcl_ooch_t* hcl_errnum_to_errstr (
|
||||
hcl_errnum_t errnum
|
||||
);
|
||||
|
||||
HCL_EXPORT hcl_errnum_t hcl_syserr_to_errnum (
|
||||
int syserr
|
||||
);
|
||||
|
||||
/**
|
||||
* The hcl_getoption() function gets the value of an option
|
||||
* specified by \a id into the buffer pointed to by \a value.
|
||||
@ -1722,6 +1735,7 @@ HCL_EXPORT hcl_pfbase_t* hcl_findpfbase (
|
||||
/* =========================================================================
|
||||
* LOGGING
|
||||
* ========================================================================= */
|
||||
|
||||
HCL_EXPORT hcl_ooi_t hcl_logbfmt (
|
||||
hcl_t* hcl,
|
||||
int mask,
|
||||
@ -1729,6 +1743,13 @@ HCL_EXPORT hcl_ooi_t hcl_logbfmt (
|
||||
...
|
||||
);
|
||||
|
||||
HCL_EXPORT hcl_ooi_t hcl_logbfmtv (
|
||||
hcl_t* hcl,
|
||||
int mask,
|
||||
const hcl_bch_t* fmt,
|
||||
va_list ap
|
||||
);
|
||||
|
||||
HCL_EXPORT hcl_ooi_t hcl_logufmt (
|
||||
hcl_t* hcl,
|
||||
int mask,
|
||||
@ -1736,10 +1757,19 @@ HCL_EXPORT hcl_ooi_t hcl_logufmt (
|
||||
...
|
||||
);
|
||||
|
||||
HCL_EXPORT hcl_ooi_t hcl_logufmtv (
|
||||
hcl_t* hcl,
|
||||
int mask,
|
||||
const hcl_uch_t* fmt,
|
||||
va_list ap
|
||||
);
|
||||
|
||||
#if defined(HCL_OOCH_IS_UCH)
|
||||
# define hcl_logoofmt hcl_logufmt
|
||||
# define hcl_logoofmtv hcl_logufmtv
|
||||
#else
|
||||
# define hcl_logoofmt hcl_logbfmt
|
||||
# define hcl_logoofmtv hcl_logbfmtv
|
||||
#endif
|
||||
|
||||
|
||||
|
35
lib/logfmt.c
35
lib/logfmt.c
@ -406,10 +406,9 @@ static int _logufmtv (hcl_t* hcl, const hcl_uch_t* fmt, hcl_fmtout_t* data, va_l
|
||||
return __logufmtv (hcl, fmt, data, ap, hcl_logbfmt);
|
||||
}
|
||||
|
||||
hcl_ooi_t hcl_logbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...)
|
||||
hcl_ooi_t hcl_logbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, va_list ap)
|
||||
{
|
||||
int x;
|
||||
va_list ap;
|
||||
hcl_fmtout_t fo;
|
||||
|
||||
if (hcl->log.default_type_mask & HCL_LOG_ALL_TYPES)
|
||||
@ -427,9 +426,7 @@ hcl_ooi_t hcl_logbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...)
|
||||
fo.putch = put_logch;
|
||||
fo.putcs = put_logcs;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = _logbfmtv (hcl, fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
|
||||
{
|
||||
@ -439,10 +436,21 @@ hcl_ooi_t hcl_logbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...)
|
||||
return (x <= -1)? -1: fo.count;
|
||||
}
|
||||
|
||||
hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...)
|
||||
hcl_ooi_t hcl_logbfmt (hcl_t* hcl, int mask, const hcl_bch_t* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
hcl_ooi_t x;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = hcl_logbfmtv (hcl, mask, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
hcl_ooi_t hcl_logufmtv (hcl_t* hcl, int mask, const hcl_uch_t* fmt, va_list ap)
|
||||
{
|
||||
int x;
|
||||
va_list ap;
|
||||
hcl_fmtout_t fo;
|
||||
|
||||
if (hcl->log.default_type_mask & HCL_LOG_ALL_TYPES)
|
||||
@ -455,9 +463,7 @@ hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...)
|
||||
fo.putch = put_logch;
|
||||
fo.putcs = put_logcs;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = _logufmtv (hcl, fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
|
||||
{
|
||||
@ -468,6 +474,19 @@ hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...)
|
||||
return (x <= -1)? -1: fo.count;
|
||||
}
|
||||
|
||||
hcl_ooi_t hcl_logufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
hcl_ooi_t x;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = hcl_logufmtv (hcl, mask, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* HELPER FOR PRINTING
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
@ -545,7 +545,7 @@ static int write_all (int fd, const char* ptr, hcl_oow_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
{
|
||||
hcl_bch_t buf[256];
|
||||
hcl_oow_t ucslen, bcslen, msgidx;
|
||||
|
243
lib/main2.c
243
lib/main2.c
@ -62,7 +62,7 @@
|
||||
/* ========================================================================= */
|
||||
|
||||
typedef struct server_xtn_t server_xtn_t;
|
||||
struct xtn_t
|
||||
struct server_xtn_t
|
||||
{
|
||||
int logfd;
|
||||
unsigned int logmask;
|
||||
@ -71,6 +71,180 @@ struct xtn_t
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
|
||||
{
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
static hcl_mmgr_t sys_mmgr =
|
||||
{
|
||||
sys_alloc,
|
||||
sys_realloc,
|
||||
sys_free,
|
||||
HCL_NULL
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
static int write_all (int fd, const char* ptr, hcl_oow_t len)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
hcl_ooi_t wr;
|
||||
|
||||
wr = write(fd, ptr, len);
|
||||
|
||||
if (wr <= -1)
|
||||
{
|
||||
#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK)
|
||||
if (errno == EAGAIN) continue;
|
||||
#else
|
||||
#if defined(EAGAIN)
|
||||
if (errno == EAGAIN) continue;
|
||||
#elif defined(EWOULDBLOCK)
|
||||
if (errno == EWOULDBLOCK) continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EINTR)
|
||||
/* TODO: would this interfere with non-blocking nature of this VM? */
|
||||
if (errno == EINTR) continue;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr += wr;
|
||||
len -= wr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void log_write (hcl_server_t* server, int wid, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len)
|
||||
{
|
||||
hcl_bch_t buf[256];
|
||||
hcl_oow_t ucslen, bcslen;
|
||||
server_xtn_t* xtn;
|
||||
hcl_oow_t msgidx;
|
||||
int n, logfd;
|
||||
|
||||
xtn = hcl_server_getxtn(server);
|
||||
|
||||
if (mask & HCL_LOG_STDERR)
|
||||
{
|
||||
/* the messages that go to STDERR don't get masked out */
|
||||
logfd = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(xtn->logmask & mask & ~HCL_LOG_ALL_LEVELS)) return; /* check log types */
|
||||
if (!(xtn->logmask & mask & ~HCL_LOG_ALL_TYPES)) return; /* check log levels */
|
||||
|
||||
if (mask & HCL_LOG_STDOUT) logfd = 1;
|
||||
else
|
||||
{
|
||||
logfd = xtn->logfd;
|
||||
if (logfd <= -1) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: beautify the log message.
|
||||
* do classification based on mask. */
|
||||
if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR)))
|
||||
{
|
||||
time_t now;
|
||||
char ts[32];
|
||||
size_t tslen;
|
||||
struct tm tm, *tmp;
|
||||
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
tmp = localtime_r (&now, &tm);
|
||||
#if defined(HAVE_STRFTIME_SMALL_Z)
|
||||
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
|
||||
#else
|
||||
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp);
|
||||
#endif
|
||||
if (tslen == 0)
|
||||
{
|
||||
strcpy (ts, "0000-00-00 00:00:00 +0000");
|
||||
tslen = 25;
|
||||
}
|
||||
|
||||
/* TODO: less write system calls by having a buffer */
|
||||
write_all (logfd, ts, tslen);
|
||||
|
||||
if (wid >= 0)
|
||||
{
|
||||
tslen = snprintf (ts, sizeof(ts), "[%x] ", wid);
|
||||
write_all (logfd, ts, tslen);
|
||||
}
|
||||
}
|
||||
|
||||
if (xtn->logfd_istty)
|
||||
{
|
||||
if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7);
|
||||
else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7);
|
||||
else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7);
|
||||
}
|
||||
|
||||
#if defined(HCL_OOCH_IS_UCH)
|
||||
msgidx = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
ucslen = len;
|
||||
bcslen = HCL_COUNTOF(buf);
|
||||
|
||||
n = hcl_conv_oocsn_to_bcsn_with_cmgr(&msg[msgidx], &ucslen, buf, &bcslen, hcl_get_utf8_cmgr());
|
||||
if (n == 0 || n == -2)
|
||||
{
|
||||
/* n = 0:
|
||||
* converted all successfully
|
||||
* n == -2:
|
||||
* buffer not sufficient. not all got converted yet.
|
||||
* write what have been converted this round. */
|
||||
|
||||
/*HCL_ASSERT (hcl, ucslen > 0); */ /* if this fails, the buffer size must be increased */
|
||||
assert (ucslen > 0);
|
||||
|
||||
/* attempt to write all converted characters */
|
||||
if (write_all(logfd, buf, bcslen) <= -1) break;
|
||||
|
||||
if (n == 0) break;
|
||||
else
|
||||
{
|
||||
msgidx += ucslen;
|
||||
len -= ucslen;
|
||||
}
|
||||
}
|
||||
else if (n <= -1)
|
||||
{
|
||||
/* conversion error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
write_all (logfd, vmsg, len);
|
||||
#endif
|
||||
|
||||
if (xtn->logfd_istty)
|
||||
{
|
||||
if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static hcl_server_t* g_server = HCL_NULL;
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -126,10 +300,12 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
|
||||
hcl_bch_t* xstr = (hcl_bch_t*)str;
|
||||
hcl_bch_t* cm, * flt;
|
||||
unsigned int logmask;
|
||||
server_xtn_t* xtn;
|
||||
|
||||
xtn = (server_xtn_t*)hcl_server_getxtn(server);
|
||||
hcl_server_getoption (server, HCL_SERVER_LOG_MASK, &logmask);
|
||||
|
||||
cm = strchr(xstr, ',');
|
||||
cm = hcl_findbcharinbcstr(xstr, ',');
|
||||
if (cm)
|
||||
{
|
||||
/* i duplicate this string for open() below as open() doesn't
|
||||
@ -141,14 +317,14 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
|
||||
return -1;
|
||||
}
|
||||
|
||||
cm = strchr(xstr, ',');
|
||||
cm = hcl_findbcharinbcstr(xstr, ',');
|
||||
*cm = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
flt = cm + 1;
|
||||
|
||||
cm = strchr(flt, ',');
|
||||
cm = hcl_findbcharinbcstr(flt, ',');
|
||||
if (cm) *cm = '\0';
|
||||
|
||||
if (hcl_compbcstr(flt, "app") == 0) logmask |= HCL_LOG_APP;
|
||||
@ -188,10 +364,9 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
|
||||
logmask = HCL_LOG_ALL_LEVELS | HCL_LOG_ALL_TYPES;
|
||||
}
|
||||
|
||||
hcl_server_setoption (server, HCL_SERVER_LOG_MASK, &logmask);
|
||||
|
||||
server->logfd = open(xstr, O_CREAT | O_WRONLY | O_APPEND , 0644);
|
||||
if (server->logfd == -1)
|
||||
xtn->logmask = logmask;
|
||||
xtn->logfd = open(xstr, O_CREAT | O_WRONLY | O_APPEND , 0644);
|
||||
if (xtn->logfd == -1)
|
||||
{
|
||||
fprintf (stderr, "ERROR: cannot open a log file %s\n", xstr);
|
||||
if (str != xstr) free (xstr);
|
||||
@ -199,7 +374,7 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
|
||||
}
|
||||
|
||||
#if defined(HAVE_ISATTY)
|
||||
server->logfd_istty = isatty(server->logfd);
|
||||
xtn->logfd_istty = isatty(xtn->logfd);
|
||||
#endif
|
||||
|
||||
if (str != xstr) free (xstr);
|
||||
@ -207,21 +382,23 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
|
||||
}
|
||||
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
static int parse_dbgopt (const char* str, unsigned int* dbgoptp)
|
||||
static int handle_dbgopt (hcl_server_t* server, const char* str)
|
||||
{
|
||||
const hcl_bch_t* cm, * flt;
|
||||
hcl_oow_t len;
|
||||
unsigned int dbgopt = 0;
|
||||
unsigned int trait;
|
||||
|
||||
hcl_server_getoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
|
||||
cm = str - 1;
|
||||
do
|
||||
{
|
||||
flt = cm + 1;
|
||||
|
||||
cm = strchr(flt, ',');
|
||||
len = cm? (cm - flt): strlen(flt);
|
||||
if (strncasecmp(flt, "gc", len) == 0) dbgopt |= HCL_DEBUG_GC;
|
||||
else if (strncasecmp (flt, "bigint", len) == 0) dbgopt |= HCL_DEBUG_BIGINT;
|
||||
cm = hcl_findbcharinbcstr(flt, ',');
|
||||
len = cm? (cm - flt): hcl_countbcstr(flt);
|
||||
if (hcl_compbcharsbcstr(flt, len, "gc") == 0) trait |= HCL_SERVER_TRAIT_DEBUG_GC;
|
||||
else if (hcl_compbcharsbcstr(flt, len, "bigint") == 0) trait |= HCL_SERVER_TRAIT_DEBUG_BIGINT;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "ERROR: unknown debug option value - %.*s\n", (int)len, flt);
|
||||
@ -230,7 +407,7 @@ static int parse_dbgopt (const char* str, unsigned int* dbgoptp)
|
||||
}
|
||||
while (cm);
|
||||
|
||||
*dbgoptp = dbgopt;
|
||||
hcl_server_setoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -260,12 +437,13 @@ int main (int argc, char* argv[])
|
||||
|
||||
hcl_server_t* server;
|
||||
server_xtn_t* xtn;
|
||||
hcl_server_prim_t server_prim;
|
||||
int n;
|
||||
|
||||
const char* logopt = HCL_NULL;
|
||||
const char* dbgopt = HCL_NULL;
|
||||
hcl_oow_t memsize = MIN_MEMSIZE;
|
||||
int large_pages = 0;
|
||||
unsigned int dbgopt = 0;
|
||||
unsigned int trait;
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@ -299,7 +477,7 @@ int main (int argc, char* argv[])
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
else if (hcl_compbcstr(opt.lngopt, "debug") == 0)
|
||||
{
|
||||
if (parse_dbgopt (opt.arg, &dbgopt) <= -1) return -1;
|
||||
dbgopt = opt.arg;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -321,7 +499,10 @@ int main (int argc, char* argv[])
|
||||
|
||||
if (opt.ind >= argc) goto print_usage;
|
||||
|
||||
server = hcl_server_open(HCL_SIZEOF(xtn_t), dbgopt);
|
||||
memset (&server_prim, 0, HCL_SIZEOF(server_prim));
|
||||
server_prim.log_write = log_write;
|
||||
|
||||
server = hcl_server_open(&sys_mmgr, HCL_SIZEOF(server_xtn_t), &server_prim, HCL_NULL);
|
||||
if (!server)
|
||||
{
|
||||
fprintf (stderr, "cannot open server\n");
|
||||
@ -332,16 +513,27 @@ int main (int argc, char* argv[])
|
||||
xtn->logfd = -1;
|
||||
xtn->logfd_istty = 0;
|
||||
|
||||
if (logopt)
|
||||
{
|
||||
if (handle_logopt(server, logopt) <= -1) goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtn->logmask = HCL_LOG_ALL_TYPES | HCL_LOG_ERROR | HCL_LOG_FATAL;
|
||||
}
|
||||
|
||||
if (dbgopt)
|
||||
{
|
||||
if (handle_dbgopt(server, dbgopt) <= -1) goto oops;
|
||||
}
|
||||
|
||||
hcl_server_getoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
if (large_pages) trait |= HCL_SERVER_TRAIT_USE_LARGE_PAGES;
|
||||
else trait &= HCL_SERVER_TRAIT_USE_LARGE_PAGES;
|
||||
else trait &= ~HCL_SERVER_TRAIT_USE_LARGE_PAGES;
|
||||
hcl_server_setoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
|
||||
/*hcl_server_setoption (server, HCL_SERVER_WORKER_STACK_SIZE, ???);*/
|
||||
hcl_server_setoption (server, HCL_SERVER_ACTOR_HEAP_SIZE, &memsize);
|
||||
/*hcl_server_setoption (server, HCL_SERVER_ACTOR_DEBUG, &memsize);*/
|
||||
|
||||
g_server = server;
|
||||
set_signal (SIGINT, handle_sigint);
|
||||
@ -353,6 +545,15 @@ int main (int argc, char* argv[])
|
||||
set_signal_to_default (SIGPIPE);
|
||||
g_server = NULL;
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
hcl_server_logbfmt (server, HCL_LOG_APP | HCL_LOG_FATAL, "server error[%d] - %js\n", hcl_server_geterrnum(server), hcl_server_geterrmsg(server));
|
||||
}
|
||||
|
||||
close (xtn->logfd);
|
||||
xtn->logfd = -1;
|
||||
xtn->logfd_istty = 0;
|
||||
|
||||
hcl_server_close (server);
|
||||
return n;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user