From 7f0428d2885fb02fb06f9a521813718cd261ba36 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 2 Nov 2018 14:15:28 +0000 Subject: [PATCH] cleaned up some code --- lib/Makefile.am | 1 + lib/Makefile.in | 1 + lib/cb-impl.h | 794 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/err.c | 234 ++++---------- lib/exec.c | 6 +- lib/hcl-cmn.h | 14 +- lib/hcl-s.c | 468 ++-------------------------- lib/hcl.h | 19 +- lib/main.c | 693 +----------------------------------------- lib/tmr.c | 8 +- 10 files changed, 914 insertions(+), 1324 deletions(-) create mode 100644 lib/cb-impl.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 2ea1b9a..3262f07 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -64,6 +64,7 @@ libhcl_la_SOURCES = \ hcl-utl.h \ hcl-prv.h \ bigint.c \ + cb-impl.h \ comp.c \ debug.c \ decode.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in index c2f2751..7524f67 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -467,6 +467,7 @@ libhcl_la_SOURCES = \ hcl-utl.h \ hcl-prv.h \ bigint.c \ + cb-impl.h \ comp.c \ debug.c \ decode.c \ diff --git a/lib/cb-impl.h b/lib/cb-impl.h new file mode 100644 index 0000000..883ace6 --- /dev/null +++ b/lib/cb-impl.h @@ -0,0 +1,794 @@ +/* this function contains commonly used callback functions for hcl */ + +/* ----------------------------------------------------------------- + * SYSTEM ERROR CONVERSION + * ----------------------------------------------------------------- */ +static hcl_errnum_t errno_to_errnum (int errcode) +{ + switch (errcode) + { + case ENOMEM: return HCL_ESYSMEM; + case EINVAL: return HCL_EINVAL; + + #if defined(EBUSY) + case EBUSY: return HCL_EBUSY; + #endif + case EACCES: return HCL_EACCES; + #if defined(EPERM) + case EPERM: return HCL_EPERM; + #endif + #if defined(ENOTDIR) + case ENOTDIR: return HCL_ENOTDIR; + #endif + case ENOENT: return HCL_ENOENT; + #if defined(EEXIST) + case EEXIST: return HCL_EEXIST; + #endif + #if defined(EINTR) + case EINTR: return HCL_EINTR; + #endif + + #if defined(EPIPE) + case EPIPE: return HCL_EPIPE; + #endif + + #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN != EWOULDBLOCK) + case EAGAIN: + case EWOULDBLOCK: return HCL_EAGAIN; + #elif defined(EAGAIN) + case EAGAIN: return HCL_EAGAIN; + #elif defined(EWOULDBLOCK) + case EWOULDBLOCK: return HCL_EAGAIN; + #endif + + #if defined(EBADF) + case EBADF: return HCL_EBADHND; + #endif + + #if defined(EIO) + case EIO: return HCL_EIOERR; + #endif + + default: return HCL_ESYSERR; + } +} + +#if defined(_WIN32) +static hcl_errnum_t winerr_to_errnum (DWORD errcode) +{ + switch (errcode) + { + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + return HCL_ESYSMEM; + + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_NAME: + return HCL_EINVAL; + + case ERROR_INVALID_HANDLE: + return HCL_EBADHND; + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + return HCL_EACCES; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return HCL_ENOENT; + + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + return HCL_EEXIST; + + case ERROR_BROKEN_PIPE: + return HCL_EPIPE; + + default: + return HCL_ESYSERR; + } +} +#endif + +#if defined(__OS2__) +static hcl_errnum_t os2err_to_errnum (APIRET errcode) +{ + /* APIRET e */ + switch (errcode) + { + case ERROR_NOT_ENOUGH_MEMORY: + return HCL_ESYSMEM; + + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_NAME: + return HCL_EINVAL; + + case ERROR_INVALID_HANDLE: + return HCL_EBADHND; + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + return HCL_EACCES; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + return HCL_ENOENT; + + case ERROR_ALREADY_EXISTS: + return HCL_EEXIST; + + /*TODO: add more mappings */ + default: + return HCL_ESYSERR; + } +} +#endif + +#if defined(macintosh) +static hcl_errnum_t macerr_to_errnum (int errcode) +{ + switch (e) + { + case notEnoughMemoryErr: + return HCL_ESYSMEM; + case paramErr: + return HCL_EINVAL; + + case qErr: /* queue element not found during deletion */ + case fnfErr: /* file not found */ + case dirNFErr: /* direcotry not found */ + case resNotFound: /* resource not found */ + case resFNotFound: /* resource file not found */ + case nbpNotFound: /* name not found on remove */ + return HCL_ENOENT; + + /*TODO: add more mappings */ + default: + return HCL_ESYSERR; + } +} +#endif + +static hcl_errnum_t syserrstrb (hcl_t* hcl, int syserr_type, int syserr_code, hcl_bch_t* buf, hcl_oow_t len) +{ + switch (syserr_type) + { + case 1: + #if defined(_WIN32) + if (buf) + { + DWORD rc; + rc = FormatMessageA ( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, syserr_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, len, HCL_NULL + ); + while (rc > 0 && buf[rc - 1] == '\r' || buf[rc - 1] == '\n') buf[--rc] = '\0'; + } + return winerr_to_errnum(syserr_code); + #elif defined(__OS2__) + /* TODO: convert code to string */ + if (buf) hcl_copy_bcstr (buf, len, "system error"); + return os2err_to_errnum(syserr_code); + #elif defined(macintosh) + /* TODO: convert code to string */ + if (buf) hcl_copy_bcstr (buf, len, "system error"); + return os2err_to_errnum(syserr_code); + #else + /* in other systems, errno is still the native system error code. + * fall thru */ + #endif + + case 0: + #if defined(HAVE_STRERROR_R) + if (buf) strerror_r (syserr_code, buf, len); + #else + /* this is not thread safe */ + if (buf) hcl_copy_bcstr (buf, len, strerror(syserr_code)); + #endif + return errno_to_errnum(syserr_code); + } + + if (buf) hcl_copy_bcstr (buf, len, "system error"); + return HCL_ESYSERR; +} + + +/* ----------------------------------------------------------------- + * HEAP ALLOCATION + * ----------------------------------------------------------------- */ + +static void* alloc_heap (hcl_t* hcl, hcl_oow_t size) +{ +#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(MAP_ANONYMOUS) + /* It's called via hcl_makeheap() when HCL creates a GC heap. + * The heap is large in size. I can use a different memory allocation + * function instead of an ordinary malloc. + * upon failure, it doesn't require to set error information as hcl_makeheap() + * set the error number to HCL_EOOMEM. */ + +#if !defined(MAP_HUGETLB) && (defined(__amd64__) || defined(__x86_64__)) +# define MAP_HUGETLB 0x40000 +#endif + + hcl_oow_t* ptr; + int flags; + hcl_oow_t actual_size; + + flags = MAP_PRIVATE | MAP_ANONYMOUS; + + #if defined(MAP_HUGETLB) + flags |= MAP_HUGETLB; + #endif + + #if defined(MAP_UNINITIALIZED) + flags |= MAP_UNINITIALIZED; + #endif + + actual_size = HCL_SIZEOF(hcl_oow_t) + size; + actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024); + ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) + { + #if defined(MAP_HUGETLB) + flags &= ~MAP_HUGETLB; + ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ptr == MAP_FAILED) return HCL_NULL; + #else + return HCL_NULL; + #endif + } + *ptr = actual_size; + + return (void*)(ptr + 1); + +#else + return HCL_MMGR_ALLOC(hcl->mmgr, size); +#endif +} + +static void free_heap (hcl_t* hcl, void* ptr) +{ +#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) + hcl_oow_t* actual_ptr; + actual_ptr = (hcl_oow_t*)ptr - 1; + munmap (actual_ptr, *actual_ptr); +#else + return HCL_MMGR_FREE(hcl->mmgr, ptr); +#endif +} + + +/* ----------------------------------------------------------------- + * POSSIBLY MONOTONIC TIME + * ----------------------------------------------------------------- */ + +static void vm_gettime (hcl_t* hcl, hcl_ntime_t* now) +{ +#if defined(_WIN32) + + #if defined(_WIN64) || (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)) + hcl_uint64_t bigsec, bigmsec; + bigmsec = GetTickCount64(); + #else + xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + hcl_uint64_t bigsec, bigmsec; + DWORD msec; + + msec = GetTickCount(); /* this can sustain for 49.7 days */ + if (msec < xtn->tc_last) + { + /* i assume the difference is never bigger than 49.7 days */ + /*diff = (HCL_TYPE_MAX(DWORD) - xtn->tc_last) + 1 + msec;*/ + xtn->tc_overflow++; + bigmsec = ((hcl_uint64_t)HCL_TYPE_MAX(DWORD) * xtn->tc_overflow) + msec; + } + else bigmsec = msec; + xtn->tc_last = msec; + #endif + + bigsec = HCL_MSEC_TO_SEC(bigmsec); + bigmsec -= HCL_SEC_TO_MSEC(bigsec); + HCL_INIT_NTIME(now, bigsec, HCL_MSEC_TO_NSEC(bigmsec)); + +#elif defined(__OS2__) + xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + hcl_uint64_t bigsec, bigmsec; + ULONG msec; + +/* TODO: use DosTmrQueryTime() and DosTmrQueryFreq()? */ + DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, &msec, HCL_SIZEOF(msec)); /* milliseconds */ + /* it must return NO_ERROR */ + if (msec < xtn->tc_last) + { + xtn->tc_overflow++; + bigmsec = ((hcl_uint64_t)HCL_TYPE_MAX(ULONG) * xtn->tc_overflow) + msec; + } + else bigmsec = msec; + xtn->tc_last = msec; + + bigsec = HCL_MSEC_TO_SEC(bigmsec); + bigmsec -= HCL_SEC_TO_MSEC(bigsec); + HCL_INIT_NTIME (now, bigsec, HCL_MSEC_TO_NSEC(bigmsec)); + +#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) + clock_t c; + +/* TODO: handle overflow?? */ + c = clock (); + now->sec = c / CLOCKS_PER_SEC; + #if (CLOCKS_PER_SEC == 100) + now->nsec = HCL_MSEC_TO_NSEC((c % CLOCKS_PER_SEC) * 10); + #elif (CLOCKS_PER_SEC == 1000) + now->nsec = HCL_MSEC_TO_NSEC(c % CLOCKS_PER_SEC); + #elif (CLOCKS_PER_SEC == 1000000L) + now->nsec = HCL_USEC_TO_NSEC(c % CLOCKS_PER_SEC); + #elif (CLOCKS_PER_SEC == 1000000000L) + now->nsec = (c % CLOCKS_PER_SEC); + #else + # error UNSUPPORTED CLOCKS_PER_SEC + #endif + +#elif defined(macintosh) + UnsignedWide tick; + hcl_uint64_t tick64; + Microseconds (&tick); + tick64 = *(hcl_uint64_t*)&tick; + HCL_INIT_NTIME (now, HCL_USEC_TO_SEC(tick64), HCL_USEC_TO_NSEC(tick64)); +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + HCL_INIT_NTIME(now, ts.tv_sec, ts.tv_nsec); +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) + struct timespec ts; + clock_gettime (CLOCK_REALTIME, &ts); + HCL_INIT_NTIME(now, ts.tv_sec, ts.tv_nsec); +#else + struct timeval tv; + gettimeofday (&tv, HCL_NULL); + HCL_INIT_NTIME(now, tv.tv_sec, HCL_USEC_TO_NSEC(tv.tv_usec)); +#endif +} + +/* ----------------------------------------------------------------- + * SLEEPING + * ----------------------------------------------------------------- */ + +#if defined(__DOS__) +# if defined(_INTELC32_) + void _halt_cpu (void); +# elif defined(__WATCOMC__) + void _halt_cpu (void); +# pragma aux _halt_cpu = "hlt" +# endif +#endif + +static void vm_sleep (hcl_t* hcl, const hcl_ntime_t* dur) +{ +#if defined(_WIN32) + xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + if (xtn->waitable_timer) + { + LARGE_INTEGER li; + li.QuadPart = -HCL_SECNSEC_TO_NSEC(dur->sec, dur->nsec); + if(SetWaitableTimer(xtn->waitable_timer, &li, 0, HCL_NULL, HCL_NULL, FALSE) == FALSE) goto normal_sleep; + WaitForSingleObject(xtn->waitable_timer, INFINITE); + } + else + { + normal_sleep: + /* fallback to normal Sleep() */ + Sleep (HCL_SECNSEC_TO_MSEC(dur->sec,dur->nsec)); + } +#elif defined(__OS2__) + + /* TODO: in gui mode, this is not a desirable method??? + * this must be made event-driven coupled with the main event loop */ + DosSleep (HCL_SECNSEC_TO_MSEC(dur->sec,dur->nsec)); + +#elif defined(macintosh) + + /* TODO: ... */ + +#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) + + clock_t c; + + c = clock (); + c += dur->sec * CLOCKS_PER_SEC; + + #if (CLOCKS_PER_SEC == 100) + c += HCL_NSEC_TO_MSEC(dur->nsec) / 10; + #elif (CLOCKS_PER_SEC == 1000) + c += HCL_NSEC_TO_MSEC(dur->nsec); + #elif (CLOCKS_PER_SEC == 1000000L) + c += HCL_NSEC_TO_USEC(dur->nsec); + #elif (CLOCKS_PER_SEC == 1000000000L) + c += dur->nsec; + #else + # error UNSUPPORTED CLOCKS_PER_SEC + #endif + +/* TODO: handle clock overvlow */ +/* TODO: check if there is abortion request or interrupt */ + while (c > clock()) + { + _halt_cpu(); + } + +#else + #if defined(HAVE_NANOSLEEP) + struct timespec ts; + ts.tv_sec = dur->sec; + ts.tv_nsec = dur->nsec; + nanosleep (&ts, HCL_NULL); + #elif defined(HAVE_USLEEP) + usleep (HCL_SECNSEC_TO_USEC(dur->sec, dur->nsec)); + #else + # error UNSUPPORT SLEEP + #endif +#endif +} + + + +/* ----------------------------------------------------------------- + * SHARED LIBRARY HANDLING + * ----------------------------------------------------------------- */ + +#if defined(USE_LTDL) +# define sys_dl_error() lt_dlerror() +# define sys_dl_open(x) lt_dlopen(x) +# define sys_dl_openext(x) lt_dlopenext(x) +# define sys_dl_close(x) lt_dlclose(x) +# define sys_dl_getsym(x,n) lt_dlsym(x,n) + +#elif defined(USE_DLFCN) +# define sys_dl_error() dlerror() +# define sys_dl_open(x) dlopen(x,RTLD_NOW) +# define sys_dl_openext(x) dlopen(x,RTLD_NOW) +# define sys_dl_close(x) dlclose(x) +# define sys_dl_getsym(x,n) dlsym(x,n) + +#elif defined(USE_WIN_DLL) +# define sys_dl_error() win_dlerror() +# define sys_dl_open(x) LoadLibraryExA(x, MOO_NULL, 0) +# define sys_dl_openext(x) LoadLibraryExA(x, MOO_NULL, 0) +# define sys_dl_close(x) FreeLibrary(x) +# define sys_dl_getsym(x,n) GetProcAddress(x,n) + +#elif defined(USE_MACH_O_DYLD) +# define sys_dl_error() mach_dlerror() +# define sys_dl_open(x) mach_dlopen(x) +# define sys_dl_openext(x) mach_dlopen(x) +# define sys_dl_close(x) mach_dlclose(x) +# define sys_dl_getsym(x,n) mach_dlsym(x,n) +#endif + +#if defined(USE_WIN_DLL) + +static const char* win_dlerror (void) +{ + /* TODO: handle wchar_t, moo_ooch_t etc? */ + static char buf[256]; + DWORD rc; + + rc = FormatMessageA ( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, MOO_COUNTOF(buf), MOO_NULL + ); + while (rc > 0 && buf[rc - 1] == '\r' || buf[rc - 1] == '\n') + { + buf[--rc] = '\0'; + } + return buf; +} + +#elif defined(USE_MACH_O_DYLD) +static const char* mach_dlerror_str = ""; + +static void* mach_dlopen (const char* path) +{ + NSObjectFileImage image; + NSObjectFileImageReturnCode rc; + void* handle; + + mach_dlerror_str = ""; + if ((rc = NSCreateObjectFileImageFromFile(path, &image)) != NSObjectFileImageSuccess) + { + switch (rc) + { + case NSObjectFileImageFailure: + case NSObjectFileImageFormat: + mach_dlerror_str = "unable to crate object file image"; + break; + + case NSObjectFileImageInappropriateFile: + mach_dlerror_str = "inappropriate file"; + break; + + case NSObjectFileImageArch: + mach_dlerror_str = "incompatible architecture"; + break; + + case NSObjectFileImageAccess: + mach_dlerror_str = "inaccessible file"; + break; + + default: + mach_dlerror_str = "unknown error"; + break; + } + return HCL_NULL; + } + handle = (void*)NSLinkModule(image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage (image); + return handle; +} + +static HCL_INLINE void mach_dlclose (void* handle) +{ + mach_dlerror_str = ""; + NSUnLinkModule (handle, NSUNLINKMODULE_OPTION_NONE); +} + +static HCL_INLINE void* mach_dlsym (void* handle, const char* name) +{ + mach_dlerror_str = ""; + return (void*)NSAddressOfSymbol(NSLookupSymbolInModule(handle, name)); +} + +static const char* mach_dlerror (void) +{ + int err_no; + const char* err_file; + NSLinkEditErrors err; + + if (mach_dlerror_str[0] == '\0') + NSLinkEditError (&err, &err_no, &err_file, &mach_dlerror_str); + + return mach_dlerror_str; +} +#endif + +static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags) +{ +#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) + hcl_bch_t stabuf[128], * bufptr; + hcl_oow_t ucslen, bcslen, bufcapa; + void* handle; + + #if defined(HCL_OOCH_IS_UCH) + if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bufcapa) <= -1) return HCL_NULL; + /* +1 for terminating null. but it's not needed because HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + * and HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTIFX) include the terminating nulls. Never mind about + * the extra 2 characters. */ + #else + bufcapa = hcl_count_bcstr(name); + #endif + bufcapa += HCL_COUNTOF(HCL_DEFAULT_PFMODDIR) + HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTFIX) + 1; + + if (bufcapa <= HCL_COUNTOF(stabuf)) bufptr = stabuf; + else + { + bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); + if (!bufptr) return HCL_NULL; + } + + if (flags & HCL_VMPRIM_DLOPEN_PFMOD) + { + hcl_oow_t len, i, xlen, dlen; + + /* opening a primitive function module - mostly libhcl-xxxx. + * if PFMODPREFIX is absolute, never use PFMODDIR */ + dlen = IS_PATH_ABSOLUTE(HCL_DEFAULT_PFMODPREFIX)? + 0: hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODDIR); + len = hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODPREFIX); + len += dlen; + + bcslen = bufcapa - len; + #if defined(HCL_OOCH_IS_UCH) + hcl_convootobcstr(hcl, name, &ucslen, &bufptr[len], &bcslen); + #else + bcslen = hcl_copy_bcstr(&bufptr[len], bcslen, name); + #endif + + /* length including the directory, the prefix and the name. but excluding the postfix */ + xlen = len + bcslen; + + for (i = len; i < xlen; i++) + { + /* convert a period(.) to a dash(-) */ + if (bufptr[i] == '.') bufptr[i] = '-'; + } + + retry: + hcl_copy_bcstr (&bufptr[xlen], bufcapa - xlen, HCL_DEFAULT_PFMODPOSTFIX); + + /* both prefix and postfix attached. for instance, libhcl-xxx */ + handle = sys_dl_openext(bufptr); + if (!handle) + { + HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[dlen], name, sys_dl_error()); + + if (dlen > 0) + { + handle = sys_dl_openext(&bufptr[0]); + if (handle) goto pfmod_open_ok; + HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[0], name, sys_dl_error()); + } + + /* try without prefix and postfix */ + bufptr[xlen] = '\0'; + handle = sys_dl_openext(&bufptr[len]); + if (!handle) + { + hcl_bch_t* dash; + const hcl_bch_t* dl_errstr; + dl_errstr = sys_dl_error(); + HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr); + hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) PFMOD %js - %hs", name, dl_errstr); + + dash = hcl_rfind_bchar(bufptr, hcl_count_bcstr(bufptr), '-'); + if (dash) + { + /* remove a segment at the back. + * [NOTE] a dash contained in the original name before + * period-to-dash transformation may cause extraneous/wrong + * loading reattempts. */ + xlen = dash - bufptr; + goto retry; + } + } + else + { + HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[len], name, handle); + } + } + else + { + pfmod_open_ok: + HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[dlen], name, handle); + } + } + else + { + /* opening a raw shared object without a prefix and/or a postfix */ + #if defined(HCL_OOCH_IS_UCH) + bcslen = bufcapa; + hcl_convootobcstr(hcl, name, &ucslen, bufptr, &bcslen); + #else + bcslen = hcl_copy_bcstr(bufptr, bufcapa, name); + #endif + + if (hcl_find_bchar(bufptr, bcslen, '.')) + { + handle = sys_dl_open(bufptr); + if (!handle) + { + const hcl_bch_t* dl_errstr; + dl_errstr = sys_dl_error(); + HCL_DEBUG2 (hcl, "Unable to open DL %hs - %hs\n", bufptr, dl_errstr); + hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, dl_errstr); + } + else HCL_DEBUG2 (hcl, "Opened DL %hs handle %p\n", bufptr, handle); + } + else + { + handle = sys_dl_openext(bufptr); + if (!handle) + { + const hcl_bch_t* dl_errstr; + dl_errstr = sys_dl_error(); + HCL_DEBUG2 (hcl, "Unable to open(ext) DL %hs - %s\n", bufptr, dl_errstr); + hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr); + } + else HCL_DEBUG2 (hcl, "Opened(ext) DL %hs handle %p\n", bufptr, handle); + } + } + + if (bufptr != stabuf) hcl_freemem (hcl, bufptr); + return handle; + +#else + +/* TODO: support various platforms */ + /* TODO: implemenent this */ + HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot open %js\n", name); + hcl_seterrbfmt (hcl, HCL_ENOIMPL, "dynamic loading not implemented - cannot open %js", name); + return HCL_NULL; +#endif +} + +static void dl_close (hcl_t* hcl, void* handle) +{ +#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) + HCL_DEBUG1 (hcl, "Closed DL handle %p\n", handle); + sys_dl_close (handle); + +#else + /* TODO: implemenent this */ + HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot close handle %p\n", handle); +#endif +} + +static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name) +{ +#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) + hcl_bch_t stabuf[64], * bufptr; + hcl_oow_t bufcapa, ucslen, bcslen, i; + const hcl_bch_t* symname; + void* sym; + + #if defined(HCL_OOCH_IS_UCH) + if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bcslen) <= -1) return HCL_NULL; + #else + bcslen = hcl_count_bcstr (name); + #endif + + if (bcslen >= HCL_COUNTOF(stabuf) - 2) + { + bufcapa = bcslen + 3; + bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); + if (!bufptr) return HCL_NULL; + } + else + { + bufcapa = HCL_COUNTOF(stabuf); + bufptr = stabuf; + } + + bcslen = bufcapa - 1; + #if defined(HCL_OOCH_IS_UCH) + hcl_convootobcstr (hcl, name, &ucslen, &bufptr[1], &bcslen); + #else + bcslen = hcl_copy_bcstr(&bufptr[1], bcslen, name); + #endif + + /* convert a period(.) to an underscore(_) */ + for (i = 1; i <= bcslen; i++) if (bufptr[i] == '.') bufptr[i] = '_'; + + symname = &bufptr[1]; /* try the name as it is */ + + sym = sys_dl_getsym(handle, symname); + if (!sym) + { + bufptr[0] = '_'; + symname = &bufptr[0]; /* try _name */ + sym = sys_dl_getsym(handle, symname); + if (!sym) + { + bufptr[bcslen + 1] = '_'; + bufptr[bcslen + 2] = '\0'; + + symname = &bufptr[1]; /* try name_ */ + sym = sys_dl_getsym(handle, symname); + + if (!sym) + { + symname = &bufptr[0]; /* try _name_ */ + sym = sys_dl_getsym(handle, symname); + if (!sym) + { + const hcl_bch_t* dl_errstr; + dl_errstr = sys_dl_error(); + HCL_DEBUG3 (hcl, "Failed to get module symbol %js from handle %p - %hs\n", name, handle, dl_errstr); + hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to get module symbol %hs - %hs", symname, dl_errstr); + + } + } + } + } + + if (sym) HCL_DEBUG3 (hcl, "Loaded module symbol %js from handle %p - %hs\n", name, handle, symname); + if (bufptr != stabuf) hcl_freemem (hcl, bufptr); + return sym; + +#else + /* TODO: IMPLEMENT THIS */ + HCL_DEBUG2 (hcl, "Dynamic loading not implemented - Cannot load module symbol %js from handle %p\n", name, handle); + hcl_seterrbfmt (hcl, HCL_ENOIMPL, "dynamic loading not implemented - Cannot load module symbol %js from handle %p", name, handle); + return HCL_NULL; +#endif +} diff --git a/lib/err.c b/lib/err.c index d0a6c4e..35ea53f 100644 --- a/lib/err.c +++ b/lib/err.c @@ -163,167 +163,6 @@ static const hcl_bch_t* synerr_to_errstr (hcl_synerrnum_t errnum) return (errnum >= 0 && errnum < HCL_COUNTOF(synerrstr))? synerrstr[errnum]: e_unknown; } -/* -------------------------------------------------------------------------- - * SYSTEM DEPENDENT FUNCTIONS - * -------------------------------------------------------------------------- */ - -#if defined(HAVE_EXECINFO_H) -# include -# include -#endif - -#if defined(_WIN32) -# include -#elif defined(__OS2__) -# define INCL_DOSPROCESS -# define INCL_DOSFILEMGR -# define INCL_DOSERRORS -# include -#elif defined(__DOS__) -# include -# if defined(_INTELC32_) -# define DOS_EXIT 0x4C -# else -# include -# endif -# include -#elif defined(vms) || defined(__vms) -# define __NEW_STARLET 1 -# include /* (SYS$...) */ -# include /* (SS$...) */ -# include /* (lib$...) */ -#elif defined(macintosh) -# include -# include -# include -# include -#else -# include -# include -# include -# include -#endif - -hcl_errnum_t hcl_syserr_to_errnum (int e) -{ -#if defined(_WIN32) - switch (e) - { - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_OUTOFMEMORY: - return HCL_ESYSMEM; - case ERROR_INVALID_PARAMETER: - case ERROR_INVALID_HANDLE: - case ERROR_INVALID_NAME: - return HCL_EINVAL; - case ERROR_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: - return HCL_EACCES; - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - return HCL_ENOENT; - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - return HCL_EEXIST; - case ERROR_BROKEN_PIPE: - return HCL_EPIPE; - - /*TODO: add more mappings */ - default: - return HCL_ESYSERR; - } - -#elif defined(__OS2__) - /* APIRET e */ - switch (e) - { - case ERROR_NOT_ENOUGH_MEMORY: return HCL_ESYSMEM; - - case ERROR_INVALID_PARAMETER: - case ERROR_INVALID_HANDLE: - case ERROR_INVALID_NAME: return HCL_EINVAL; - - case ERROR_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: return HCL_EACCES; - - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: return HCL_ENOENT; - - case ERROR_ALREADY_EXISTS: return HCL_EEXIST; - - /*TODO: add more mappings */ - default: return HCL_ESYSERR; - } -#elif defined(macintosh) - switch (e) - { - case notEnoughMemoryErr: return HCL_ESYSMEM; - case paramErr: return HCL_EINVAL; - - case qErr: /* queue element not found during deletion */ - case fnfErr: /* file not found */ - case dirNFErr: /* direcotry not found */ - case resNotFound: /* resource not found */ - case resFNotFound: /* resource file not found */ - case nbpNotFound: /* name not found on remove */ - return HCL_ENOENT; - - /*TODO: add more mappings */ - default: return HCL_ESYSERR; - } - -#else - switch (e) - { - case ENOMEM: return HCL_ESYSMEM; - case EINVAL: return HCL_EINVAL; - - #if defined(EBUSY) - case EBUSY: return HCL_EBUSY; - #endif - case EACCES: return HCL_EACCES; - #if defined(EPERM) - case EPERM: return HCL_EPERM; - #endif - #if defined(ENOTDIR) - case ENOTDIR: return HCL_ENOTDIR; - #endif - case ENOENT: return HCL_ENOENT; - #if defined(EEXIST) - case EEXIST: return HCL_EEXIST; - #endif - #if defined(EINTR) - case EINTR: return HCL_EINTR; - #endif - - #if defined(EPIPE) - case EPIPE: return HCL_EPIPE; - #endif - - #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN != EWOULDBLOCK) - case EAGAIN: - case EWOULDBLOCK: return HCL_EAGAIN; - #elif defined(EAGAIN) - case EAGAIN: return HCL_EAGAIN; - #elif defined(EWOULDBLOCK) - case EWOULDBLOCK: return HCL_EAGAIN; - #endif - - #if defined(EBADF) - case EBADF: return HCL_EBADHND; - #endif - - - - #if defined(EIO) - case EIO: return HCL_EIOERR; - #endif - - default: return HCL_ESYSERR; - } -#endif -} - /* -------------------------------------------------------------------------- * ERROR NUMBER/MESSAGE HANDLING * -------------------------------------------------------------------------- */ @@ -352,20 +191,22 @@ void hcl_seterrnum (hcl_t* hcl, hcl_errnum_t errnum) hcl->errmsg.len = 0; } -void hcl_seterrwithsyserr (hcl_t* hcl, int syserr) +void hcl_seterrwithsyserr (hcl_t* hcl, int syserr_type, int syserr_code) { + hcl_errnum_t errnum; + if (hcl->shuterr) return; if (hcl->vmprim.syserrstrb) { - hcl->vmprim.syserrstrb (hcl, syserr, hcl->errmsg.tmpbuf.bch, HCL_COUNTOF(hcl->errmsg.tmpbuf.bch)); - hcl_seterrbfmt (hcl, hcl_syserr_to_errnum(syserr), "%hs", hcl->errmsg.tmpbuf.bch); + errnum = hcl->vmprim.syserrstrb(hcl, syserr_type, syserr_code, hcl->errmsg.tmpbuf.bch, HCL_COUNTOF(hcl->errmsg.tmpbuf.bch)); + hcl_seterrbfmt (hcl, errnum, "%hs", hcl->errmsg.tmpbuf.bch); } else { HCL_ASSERT (hcl, hcl->vmprim.syserrstru != HCL_NULL); - hcl->vmprim.syserrstru (hcl, syserr, hcl->errmsg.tmpbuf.uch, HCL_COUNTOF(hcl->errmsg.tmpbuf.uch)); - hcl_seterrbfmt (hcl, hcl_syserr_to_errnum(syserr), "%ls", hcl->errmsg.tmpbuf.uch); + errnum = hcl->vmprim.syserrstru(hcl, syserr_type, syserr_code, hcl->errmsg.tmpbuf.uch, HCL_COUNTOF(hcl->errmsg.tmpbuf.uch)); + hcl_seterrbfmt (hcl, errnum, "%ls", hcl->errmsg.tmpbuf.uch); } } @@ -484,8 +325,61 @@ void hcl_setsynerrufmt (hcl_t* hcl, hcl_synerrnum_t num, const hcl_ioloc_t* loc, } /* -------------------------------------------------------------------------- - * STACK FRAME BACKTRACE + * ASSERTION SUPPORT * -------------------------------------------------------------------------- */ + +#if defined(HCL_BUILD_RELEASE) + +void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) +{ + /* do nothing */ +} + +#else /* defined(HCL_BUILD_RELEASE) */ + +/* -------------------------------------------------------------------------- + * SYSTEM DEPENDENT HEADERS + * -------------------------------------------------------------------------- */ +#if defined(HCL_ENABLE_LIBUNWIND) +# include +#elif defined(HAVE_EXECINFO_H) +# include +# include +#endif + +#if defined(_WIN32) +# include +# include +#elif defined(__OS2__) +# define INCL_DOSPROCESS +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# include +#elif defined(__DOS__) +# include +# if defined(_INTELC32_) +# define DOS_EXIT 0x4C +# else +# include +# endif +# include +#elif defined(vms) || defined(__vms) +# define __NEW_STARLET 1 +# include /* (SYS$...) */ +# include /* (SS$...) */ +# include /* (lib$...) */ +#elif defined(macintosh) +# include +# include +# include +# include +#else +# include +# include +# include +# include +#endif + #if defined(HCL_ENABLE_LIBUNWIND) static void backtrace_stack_frames (hcl_t* hcl) { @@ -543,10 +437,6 @@ static void backtrace_stack_frames (hcl_t* hcl) } #endif -/* -------------------------------------------------------------------------- - * ASSERTION FAILURE HANDLERsemaphore heap full - * -------------------------------------------------------------------------- */ - void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) { hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line); @@ -578,3 +468,5 @@ void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, _exit (1); #endif } + +#endif /* defined(HCL_BUILD_RELEASE) */ diff --git a/lib/exec.c b/lib/exec.c index 7442ca9..aa78d70 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -1288,12 +1288,12 @@ static int execute (hcl_t* hcl) HCL_ASSERT (hcl, HCL_OOP_IS_SMOOI(hcl->sem_heap[0]->heap_ftime_sec)); HCL_ASSERT (hcl, HCL_OOP_IS_SMOOI(hcl->sem_heap[0]->heap_ftime_nsec)); - HCL_INITNTIME (&ft, + HCL_INIT_NTIME (&ft, HCL_OOP_TO_SMOOI(hcl->sem_heap[0]->heap_ftime_sec), HCL_OOP_TO_SMOOI(hcl->sem_heap[0]->heap_ftime_nsec) ); - if (HCL_CMPNTIME(&ft, (hcl_ntime_t*)&now) <= 0) + if (HCL_CMP_NTIME(&ft, (hcl_ntime_t*)&now) <= 0) { hcl_oop_process_t proc; @@ -1324,7 +1324,7 @@ static int execute (hcl_t* hcl) } else if (hcl->processor->active == hcl->nil_process) { - HCL_SUBNTIME (&ft, &ft, (hcl_ntime_t*)&now); + HCL_SUB_NTIME (&ft, &ft, (hcl_ntime_t*)&now); hcl->vmprim.vm_sleep (hcl, &ft); /* TODO: change this to i/o multiplexer??? */ hcl->vmprim.vm_gettime (hcl, &now); } diff --git a/lib/hcl-cmn.h b/lib/hcl-cmn.h index 40ce88d..361bd9a 100644 --- a/lib/hcl-cmn.h +++ b/lib/hcl-cmn.h @@ -393,31 +393,31 @@ struct hcl_ntime_t hcl_int32_t nsec; /* nanoseconds */ }; -#define HCL_INITNTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns))) -#define HCL_CLEARNTIME(c) HCL_INITNTIME(c, 0, 0) +#define HCL_INIT_NTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns))) +#define HCL_CLEAR_NTIME(c) HCL_INIT_NTIME(c, 0, 0) -#define HCL_ADDNTIME(c,a,b) \ +#define HCL_ADD_NTIME(c,a,b) \ do { \ (c)->sec = (a)->sec + (b)->sec; \ (c)->nsec = (a)->nsec + (b)->nsec; \ while ((c)->nsec >= HCL_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= HCL_NSECS_PER_SEC; } \ } while(0) -#define HCL_ADDNTIMESNS(c,a,s,ns) \ +#define HCL_ADD_NTIME_SNS(c,a,s,ns) \ do { \ (c)->sec = (a)->sec + (s); \ (c)->nsec = (a)->nsec + (ns); \ while ((c)->nsec >= HCL_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= HCL_NSECS_PER_SEC; } \ } while(0) -#define HCL_SUBNTIME(c,a,b) \ +#define HCL_SUB_NTIME(c,a,b) \ do { \ (c)->sec = (a)->sec - (b)->sec; \ (c)->nsec = (a)->nsec - (b)->nsec; \ while ((c)->nsec < 0) { (c)->sec--; (c)->nsec += HCL_NSECS_PER_SEC; } \ } while(0) -#define HCL_SUBNTIMESNS(c,a,s,ns) \ +#define HCL_SUB_NTIME_SNS(c,a,s,ns) \ do { \ (c)->sec = (a)->sec - s; \ (c)->nsec = (a)->nsec - ns; \ @@ -425,7 +425,7 @@ struct hcl_ntime_t } while(0) -#define HCL_CMPNTIME(a,b) (((a)->sec == (b)->sec)? ((a)->nsec - (b)->nsec): ((a)->sec - (b)->sec)) +#define HCL_CMP_NTIME(a,b) (((a)->sec == (b)->sec)? ((a)->nsec - (b)->nsec): ((a)->sec - (b)->sec)) /* ========================================================================= * PRIMITIVE MACROS diff --git a/lib/hcl-s.c b/lib/hcl-s.c index f9780cc..004d83f 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -43,6 +43,8 @@ # if defined(HCL_HAVE_CFG_H) && defined(HCL_ENABLE_LIBLTDL) # include # define USE_LTDL +# else +# define USE_WIN_DLL # endif #elif defined(__OS2__) # define INCL_DOSMODULEMGR @@ -59,27 +61,12 @@ # if defined(HCL_ENABLE_LIBLTDL) # include # define USE_LTDL -# define sys_dl_error() lt_dlerror() -# define sys_dl_open(x) lt_dlopen(x) -# define sys_dl_openext(x) lt_dlopenext(x) -# define sys_dl_close(x) lt_dlclose(x) -# define sys_dl_getsym(x,n) lt_dlsym(x,n) # elif defined(HAVE_DLFCN_H) # include # define USE_DLFCN -# define sys_dl_error() dlerror() -# define sys_dl_open(x) dlopen(x,RTLD_NOW) -# define sys_dl_openext(x) dlopen(x,RTLD_NOW) -# define sys_dl_close(x) dlclose(x) -# define sys_dl_getsym(x,n) dlsym(x,n) # elif defined(__APPLE__) || defined(__MACOSX__) # define USE_MACH_O_DYLD # include -# define sys_dl_error() mach_dlerror() -# define sys_dl_open(x) mach_dlopen(x) -# define sys_dl_openext(x) mach_dlopen(x) -# define sys_dl_close(x) mach_dlclose(x) -# define sys_dl_getsym(x,n) mach_dlsym(x,n) # else # error UNSUPPORTED DYNAMIC LINKER # endif @@ -542,7 +529,7 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) if (n <= -1) { if (errno == EINTR) goto start_over; - hcl_seterrwithsyserr (hcl, errno); + hcl_seterrwithsyserr (hcl, 0, errno); return -1; } else if (n >= 1) break; @@ -559,7 +546,7 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) if (x <= -1) { if (errno == EINTR) goto start_over; - hcl_seterrwithsyserr (hcl, errno); + hcl_seterrwithsyserr (hcl, 0, errno); return -1; } @@ -656,66 +643,6 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) /* ========================================================================= */ -static void* alloc_heap (hcl_t* hcl, hcl_oow_t size) -{ -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(MAP_ANONYMOUS) - /* It's called via hcl_makeheap() when HCL creates a GC heap. - * The heap is large in size. I can use a different memory allocation - * function instead of an ordinary malloc. - * upon failure, it doesn't require to set error information as hcl_makeheap() - * set the error number to HCL_EOOMEM. */ - -#if !defined(MAP_HUGETLB) && (defined(__amd64__) || defined(__x86_64__)) -# define MAP_HUGETLB 0x40000 -#endif - - hcl_oow_t* ptr; - int flags; - hcl_oow_t actual_size; - - flags = MAP_PRIVATE | MAP_ANONYMOUS; - - #if defined(MAP_HUGETLB) - flags |= MAP_HUGETLB; - #endif - - #if defined(MAP_UNINITIALIZED) - flags |= MAP_UNINITIALIZED; - #endif - - actual_size = HCL_SIZEOF(hcl_oow_t) + size; - actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024); - ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ptr == MAP_FAILED) - { - #if defined(MAP_HUGETLB) - flags &= ~MAP_HUGETLB; - ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ptr == MAP_FAILED) return HCL_NULL; - #else - return HCL_NULL; - #endif - } - *ptr = actual_size; - - return (void*)(ptr + 1); - -#else - return HCL_MMGR_ALLOC(hcl->mmgr, size); -#endif -} - -static void free_heap (hcl_t* hcl, void* ptr) -{ -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) - hcl_oow_t* actual_ptr; - actual_ptr = (hcl_oow_t*)ptr - 1; - munmap (actual_ptr, *actual_ptr); -#else - return HCL_MMGR_FREE(hcl->mmgr, ptr); -#endif -} - static void log_write (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len) { worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); @@ -738,357 +665,7 @@ static void log_write_for_dummy (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_ pthread_mutex_unlock (&server->log_mutex); } -static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len) -{ -#if defined(HAVE_STRERROR_R) - strerror_r (syserr, buf, len); -#else - /* this may not be thread safe */ - hcl_copy_bcstr (buf, len, strerror(syserr)); -#endif -} - -/* ========================================================================= */ -#if defined(USE_MACH_O_DYLD) -static const char* mach_dlerror_str = ""; - -static void* mach_dlopen (const char* path) -{ - NSObjectFileImage image; - NSObjectFileImageReturnCode rc; - void* handle; - - mach_dlerror_str = ""; - if ((rc = NSCreateObjectFileImageFromFile(path, &image)) != NSObjectFileImageSuccess) - { - switch (rc) - { - case NSObjectFileImageFailure: - case NSObjectFileImageFormat: - mach_dlerror_str = "unable to crate object file image"; - break; - - case NSObjectFileImageInappropriateFile: - mach_dlerror_str = "inappropriate file"; - break; - - case NSObjectFileImageArch: - mach_dlerror_str = "incompatible architecture"; - break; - - case NSObjectFileImageAccess: - mach_dlerror_str = "inaccessible file"; - break; - - default: - mach_dlerror_str = "unknown error"; - break; - } - return HCL_NULL; - } - handle = (void*)NSLinkModule(image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); - NSDestroyObjectFileImage (image); - return handle; -} - -static HCL_INLINE void mach_dlclose (void* handle) -{ - mach_dlerror_str = ""; - NSUnLinkModule (handle, NSUNLINKMODULE_OPTION_NONE); -} - -static HCL_INLINE void* mach_dlsym (void* handle, const char* name) -{ - mach_dlerror_str = ""; - return (void*)NSAddressOfSymbol(NSLookupSymbolInModule(handle, name)); -} - -static const char* mach_dlerror (void) -{ - int err_no; - const char* err_file; - NSLinkEditErrors err; - - if (mach_dlerror_str[0] == '\0') - NSLinkEditError (&err, &err_no, &err_file, &mach_dlerror_str); - - return mach_dlerror_str; -} -#endif - -static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - hcl_bch_t stabuf[128], * bufptr; - hcl_oow_t ucslen, bcslen, bufcapa; - void* handle; - - #if defined(HCL_OOCH_IS_UCH) - if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bufcapa) <= -1) return HCL_NULL; - /* +1 for terminating null. but it's not needed because HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) - * and HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTIFX) include the terminating nulls. Never mind about - * the extra 2 characters. */ - #else - bufcapa = hcl_count_bcstr(name); - #endif - bufcapa += HCL_COUNTOF(HCL_DEFAULT_PFMODDIR) + HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTFIX) + 1; - - if (bufcapa <= HCL_COUNTOF(stabuf)) bufptr = stabuf; - else - { - bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); - if (!bufptr) return HCL_NULL; - } - - if (flags & HCL_VMPRIM_DLOPEN_PFMOD) - { - hcl_oow_t len, i, xlen, dlen; - - /* opening a primitive function module - mostly libhcl-xxxx. - * if PFMODPREFIX is absolute, never use PFMODDIR */ - dlen = IS_PATH_ABSOLUTE(HCL_DEFAULT_PFMODPREFIX)? - 0: hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODDIR); - len = hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODPREFIX); - len += dlen; - - bcslen = bufcapa - len; - #if defined(HCL_OOCH_IS_UCH) - hcl_convootobcstr(hcl, name, &ucslen, &bufptr[len], &bcslen); - #else - bcslen = hcl_copy_bcstr(&bufptr[len], bcslen, name); - #endif - - /* length including the directory, the prefix and the name. but excluding the postfix */ - xlen = len + bcslen; - - for (i = len; i < xlen; i++) - { - /* convert a period(.) to a dash(-) */ - if (bufptr[i] == '.') bufptr[i] = '-'; - } - - retry: - hcl_copy_bcstr (&bufptr[xlen], bufcapa - xlen, HCL_DEFAULT_PFMODPOSTFIX); - - /* both prefix and postfix attached. for instance, libhcl-xxx */ - handle = sys_dl_openext(bufptr); - if (!handle) - { - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[dlen], name, sys_dl_error()); - - if (dlen > 0) - { - handle = sys_dl_openext(&bufptr[0]); - if (handle) goto pfmod_open_ok; - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[0], name, sys_dl_error()); - } - - /* try without prefix and postfix */ - bufptr[xlen] = '\0'; - handle = sys_dl_openext(&bufptr[len]); - if (!handle) - { - hcl_bch_t* dash; - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) PFMOD %js - %hs", name, dl_errstr); - - dash = hcl_rfind_bchar(bufptr, hcl_count_bcstr(bufptr), '-'); - if (dash) - { - /* remove a segment at the back. - * [NOTE] a dash contained in the original name before - * period-to-dash transformation may cause extraneous/wrong - * loading reattempts. */ - xlen = dash - bufptr; - goto retry; - } - } - else - { - HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[len], name, handle); - } - } - else - { - pfmod_open_ok: - HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[dlen], name, handle); - } - } - else - { - /* opening a raw shared object without a prefix and/or a postfix */ - #if defined(HCL_OOCH_IS_UCH) - bcslen = bufcapa; - hcl_convootobcstr(hcl, name, &ucslen, bufptr, &bcslen); - #else - bcslen = hcl_copy_bcstr(bufptr, bufcapa, name); - #endif - - if (hcl_find_bchar(bufptr, bcslen, '.')) - { - handle = sys_dl_open(bufptr); - if (!handle) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG2 (hcl, "Unable to open DL %hs - %hs\n", bufptr, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, dl_errstr); - } - else HCL_DEBUG2 (hcl, "Opened DL %hs handle %p\n", bufptr, handle); - } - else - { - handle = sys_dl_openext(bufptr); - if (!handle) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG2 (hcl, "Unable to open(ext) DL %hs - %s\n", bufptr, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr); - } - else HCL_DEBUG2 (hcl, "Opened(ext) DL %hs handle %p\n", bufptr, handle); - } - } - - if (bufptr != stabuf) hcl_freemem (hcl, bufptr); - return handle; - -#else - -/* TODO: support various platforms */ - /* TODO: implemenent this */ - HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot open %js\n", name); - hcl_seterrnum (hcl, HCL_ENOIMPL, "dynamic loading not implemented - cannot open %js", name); - return HCL_NULL; -#endif -} - -static void dl_close (hcl_t* hcl, void* handle) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - HCL_DEBUG1 (hcl, "Closed DL handle %p\n", handle); - sys_dl_close (handle); - -#else - /* TODO: implemenent this */ - HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot close handle %p\n", handle); -#endif -} - -static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - hcl_bch_t stabuf[64], * bufptr; - hcl_oow_t bufcapa, ucslen, bcslen, i; - const hcl_bch_t* symname; - void* sym; - - #if defined(HCL_OOCH_IS_UCH) - if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bcslen) <= -1) return HCL_NULL; - #else - bcslen = hcl_count_bcstr (name); - #endif - - if (bcslen >= HCL_COUNTOF(stabuf) - 2) - { - bufcapa = bcslen + 3; - bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); - if (!bufptr) return HCL_NULL; - } - else - { - bufcapa = HCL_COUNTOF(stabuf); - bufptr = stabuf; - } - - bcslen = bufcapa - 1; - #if defined(HCL_OOCH_IS_UCH) - hcl_convootobcstr (hcl, name, &ucslen, &bufptr[1], &bcslen); - #else - bcslen = hcl_copy_bcstr(&bufptr[1], bcslen, name); - #endif - - /* convert a period(.) to an underscore(_) */ - for (i = 1; i <= bcslen; i++) if (bufptr[i] == '.') bufptr[i] = '_'; - - symname = &bufptr[1]; /* try the name as it is */ - - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - bufptr[0] = '_'; - symname = &bufptr[0]; /* try _name */ - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - bufptr[bcslen + 1] = '_'; - bufptr[bcslen + 2] = '\0'; - - symname = &bufptr[1]; /* try name_ */ - sym = sys_dl_getsym(handle, symname); - - if (!sym) - { - symname = &bufptr[0]; /* try _name_ */ - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG3 (hcl, "Failed to get module symbol %js from handle %p - %hs\n", name, handle, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to get module symbol %hs - %hs", symname, dl_errstr); - - } - } - } - } - - if (sym) HCL_DEBUG3 (hcl, "Loaded module symbol %js from handle %p - %hs\n", name, handle, symname); - if (bufptr != stabuf) hcl_freemem (hcl, bufptr); - return sym; - -#else - /* TODO: IMPLEMENT THIS */ - HCL_DEBUG2 (hcl, "Dynamic loading not implemented - Cannot load module symbol %js from handle %p\n", name, handle); - hcl_seterrbfmt (hcl, HCL_ENOIMPL, "dynamic loading not implemented - Cannot load module symbol %js from handle %p", name, handle); - return HCL_NULL; -#endif -} - -/* ========================================================================= */ - -static void vm_gettime (hcl_t* hcl, hcl_ntime_t* now) -{ -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) - struct timespec ts; - clock_gettime (CLOCK_MONOTONIC, &ts); - HCL_INITNTIME(now, ts.tv_sec, ts.tv_nsec); -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) - struct timespec ts; - clock_gettime (CLOCK_REALTIME, &ts); - HCL_INITNTIME(now, ts.tv_sec, ts.tv_nsec); -#else - struct timeval tv; - gettimeofday (&tv, HCL_NULL); - HCL_INITNTIME(now, tv.tv_sec, HCL_USEC_TO_NSEC(tv.tv_usec)); -#endif -} - -static void vm_sleep (hcl_t* hcl, const hcl_ntime_t* dur) -{ -#if defined(HAVE_NANOSLEEP) - struct timespec ts; - ts.tv_sec = dur->sec; - ts.tv_nsec = dur->nsec; - nanosleep (&ts, HCL_NULL); -#elif defined(HAVE_USLEEP) - usleep (HCL_SECNSEC_TO_USEC(dur->sec, dur->nsec)); -#else -# error UNSUPPORT SLEEP -#endif -} +#include "cb-impl.h" /* ========================================================================= */ @@ -1613,7 +1190,7 @@ static int insert_exec_timer (hcl_server_proto_t* proto, const hcl_ntime_t* tmou HCL_MEMSET (&event, 0, HCL_SIZEOF(event)); event.ctx = proto; proto->hcl->vmprim.vm_gettime (proto->hcl, &event.when); - HCL_ADDNTIME (&event.when, &event.when, tmout); + HCL_ADD_NTIME (&event.when, &event.when, tmout); event.handler = exec_runtime_handler; event.updater = exec_runtime_updater; @@ -2027,7 +1604,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p if (pipe(pfd) <= -1) { - if (errnum) *errnum = hcl_syserr_to_errnum(errno); + if (errnum) *errnum = syserrstrb(hcl, 0, errno, HCL_NULL, 0); goto oops; } @@ -2071,8 +1648,8 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p server->cfg.worker_stack_size = 512000UL; server->cfg.actor_heap_size = 512000UL; - HCL_INITNTIME (&server->cfg.worker_idle_timeout, 0, 0); - HCL_INITNTIME (&server->cfg.actor_max_runtime, 0, 0); + HCL_INIT_NTIME (&server->cfg.worker_idle_timeout, 0, 0); + HCL_INIT_NTIME (&server->cfg.actor_max_runtime, 0, 0); server->mux_pipe[0] = pfd[0]; server->mux_pipe[1] = pfd[1]; @@ -2407,7 +1984,7 @@ void hcl_server_logufmt (hcl_server_t* server, hcl_bitmask_t mask, const hcl_uch va_end (ap); } -static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* bfmt, ...) +static void set_err_with_syserr (hcl_server_t* server, int syserr_type, int syserr_code, const char* bfmt, ...) { hcl_t* hcl = server->dummy_hcl; hcl_errnum_t errnum; @@ -2419,11 +1996,10 @@ static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* b if (hcl->shuterr) return; - errnum = hcl_syserr_to_errnum(syserr); if (hcl->vmprim.syserrstrb) { - hcl->vmprim.syserrstrb (hcl, syserr, hcl->errmsg.tmpbuf.bch, HCL_COUNTOF(hcl->errmsg.tmpbuf.bch)); - + errnum = hcl->vmprim.syserrstrb(hcl, syserr_type, syserr_code, hcl->errmsg.tmpbuf.bch, HCL_COUNTOF(hcl->errmsg.tmpbuf.bch)); + va_start (ap, bfmt); hcl_seterrbfmtv (hcl, errnum, bfmt, ap); va_end (ap); @@ -2443,7 +2019,7 @@ static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* b { HCL_ASSERT (hcl, hcl->vmprim.syserrstru != HCL_NULL); - hcl->vmprim.syserrstru (hcl, syserr, hcl->errmsg.tmpbuf.uch, HCL_COUNTOF(hcl->errmsg.tmpbuf.uch)); + errnum = hcl->vmprim.syserrstru(hcl, syserr_type, syserr_code, hcl->errmsg.tmpbuf.uch, HCL_COUNTOF(hcl->errmsg.tmpbuf.uch)); va_start (ap, bfmt); hcl_seterrbfmtv (hcl, errnum, bfmt, ap); @@ -2497,7 +2073,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) ep_fd = epoll_create(1024); if (ep_fd <= -1) { - set_err_with_syserr (server, errno, "unable to create multiplexer"); + set_err_with_syserr (server, 0, errno, "unable to create multiplexer"); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); return -1; } @@ -2512,7 +2088,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) ev.data.fd = server->mux_pipe[0]; if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, server->mux_pipe[0], &ev) <= -1) { - set_err_with_syserr (server, errno, "unable to register pipe %d to multiplexer", server->mux_pipe[0]); + set_err_with_syserr (server, 0, errno, "unable to register pipe %d to multiplexer", server->mux_pipe[0]); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); close (ep_fd); return -1; @@ -2543,7 +2119,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) srv_fd = socket(sck_fam, SOCK_STREAM, 0); if (srv_fd <= -1) { - set_err_with_syserr (server, errno, "unable to open server socket for %.*hs", addr_len, addr_ptr); + set_err_with_syserr (server, 0, errno, "unable to open server socket for %.*hs", addr_len, addr_ptr); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); goto next_segment; } @@ -2568,7 +2144,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) if (bind(srv_fd, (struct sockaddr*)&srv_addr, srv_len) == -1) { - set_err_with_syserr (server, errno, "unable to bind server socket %d for %.*hs", srv_fd, addr_len, addr_ptr); + set_err_with_syserr (server, 0, errno, "unable to bind server socket %d for %.*hs", srv_fd, addr_len, addr_ptr); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); close (srv_fd); goto next_segment; @@ -2576,7 +2152,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) if (listen(srv_fd, 128) <= -1) { - set_err_with_syserr (server, errno, "unable to listen on server socket %d for %.*hs", srv_fd, addr_len, addr_ptr); + set_err_with_syserr (server, 0, errno, "unable to listen on server socket %d for %.*hs", srv_fd, addr_len, addr_ptr); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); close (srv_fd); goto next_segment; @@ -2587,7 +2163,7 @@ static int setup_listeners (hcl_server_t* server, const hcl_bch_t* addrs) ev.data.fd = srv_fd; if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, srv_fd, &ev) <= -1) { - set_err_with_syserr (server, errno, "unable to register server socket %d to multiplexer for %.*hs", srv_fd, addr_len, addr_ptr); + set_err_with_syserr (server, 0, errno, "unable to register server socket %d to multiplexer for %.*hs", srv_fd, addr_len, addr_ptr); HCL_LOG1 (server->dummy_hcl, SERVER_LOGMASK_ERROR, "%js\n", hcl_server_geterrmsg(server)); close (srv_fd); goto next_segment; @@ -2648,7 +2224,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) pthread_mutex_lock (&server->tmr_mutex); n = hcl_tmr_gettmout(server->tmr, HCL_NULL, &tmout); pthread_mutex_unlock (&server->tmr_mutex); - if (n <= -1) HCL_INITNTIME (&tmout, 10, 0); + if (n <= -1) HCL_INIT_NTIME (&tmout, 10, 0); n = epoll_wait(server->listener.ep_fd, server->listener.ev_buf, HCL_COUNTOF(server->listener.ev_buf), HCL_SECNSEC_TO_MSEC(tmout.sec, tmout.nsec)); @@ -2658,7 +2234,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) if (server->stopreq) break; /* normal termination requested */ if (errno == EINTR) continue; /* interrupted but not termination requested */ - set_err_with_syserr (server, errno, "unable to poll for events in server"); + set_err_with_syserr (server, 0, errno, "unable to poll for events in server"); xret = -1; break; } @@ -2699,7 +2275,7 @@ int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs) if (errno == EAGAIN) continue; #endif - set_err_with_syserr (server, errno, "unable to accept worker on server socket %d", evp->data.fd); + set_err_with_syserr (server, 0, errno, "unable to accept worker on server socket %d", evp->data.fd); xret = -1; break; } diff --git a/lib/hcl.h b/lib/hcl.h index 6b6e9fd..6d674a9 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -266,7 +266,7 @@ typedef struct hcl_obj_word_t* hcl_oop_word_t; * are set to 1 or 2. * * This scheme works because the object allocators aligns the object size to - * a multiple of sizeof(moo_oop_t). This way, the 2 least-significant bits + * a multiple of sizeof(hcl_oop_t). This way, the 2 least-significant bits * of a real OOP are always 0s. * * With 2 bits, i can encode only 3 special types except object pointers. @@ -814,16 +814,18 @@ typedef void (*hcl_log_write_t) ( hcl_oow_t len ); -typedef void (*hcl_syserrstrb_t) ( +typedef hcl_errnum_t (*hcl_syserrstrb_t) ( hcl_t* hcl, - int syserr, + int syserr_type, + int syserr_code, hcl_bch_t* buf, hcl_oow_t len ); -typedef void (*hcl_syserrstru_t) ( +typedef hcl_errnum_t (*hcl_syserrstru_t) ( hcl_t* hcl, - int syserr, + int syserr_type, + int syserr_code, hcl_uch_t* buf, hcl_oow_t len ); @@ -1525,7 +1527,8 @@ HCL_EXPORT void hcl_seterrnum ( HCL_EXPORT void hcl_seterrwithsyserr ( hcl_t* hcl, - int syserr + int syserr_type, + int syserr_code ); HCL_EXPORT void hcl_seterrbfmt ( @@ -1572,10 +1575,6 @@ 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. diff --git a/lib/main.c b/lib/main.c index 67b778f..15ceaa2 100644 --- a/lib/main.c +++ b/lib/main.c @@ -44,6 +44,8 @@ # if defined(HCL_HAVE_CFG_H) && defined(HCL_ENABLE_LIBLTDL) # include # define USE_LTDL +# else +# define USE_WIN_DLL # endif #elif defined(__OS2__) # define INCL_DOSMODULEMGR @@ -60,27 +62,12 @@ # if defined(HCL_ENABLE_LIBLTDL) # include # define USE_LTDL -# define sys_dl_error() lt_dlerror() -# define sys_dl_open(x) lt_dlopen(x) -# define sys_dl_openext(x) lt_dlopenext(x) -# define sys_dl_close(x) lt_dlclose(x) -# define sys_dl_getsym(x,n) lt_dlsym(x,n) # elif defined(HAVE_DLFCN_H) # include # define USE_DLFCN -# define sys_dl_error() dlerror() -# define sys_dl_open(x) dlopen(x,RTLD_NOW) -# define sys_dl_openext(x) dlopen(x,RTLD_NOW) -# define sys_dl_close(x) dlclose(x) -# define sys_dl_getsym(x,n) dlsym(x,n) # elif defined(__APPLE__) || defined(__MACOSX__) # define USE_MACH_O_DYLD # include -# define sys_dl_error() mach_dlerror() -# define sys_dl_open(x) mach_dlopen(x) -# define sys_dl_openext(x) mach_dlopen(x) -# define sys_dl_close(x) mach_dlclose(x) -# define sys_dl_getsym(x,n) mach_dlsym(x,n) # else # error UNSUPPORTED DYNAMIC LINKER # endif @@ -480,66 +467,6 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) /* ========================================================================= */ -static void* alloc_heap (hcl_t* hcl, hcl_oow_t size) -{ -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(MAP_ANONYMOUS) - /* It's called via hcl_makeheap() when HCL creates a GC heap. - * The heap is large in size. I can use a different memory allocation - * function instead of an ordinary malloc. - * upon failure, it doesn't require to set error information as hcl_makeheap() - * set the error number to HCL_EOOMEM. */ - -#if !defined(MAP_HUGETLB) && (defined(__amd64__) || defined(__x86_64__)) -# define MAP_HUGETLB 0x40000 -#endif - - hcl_oow_t* ptr; - int flags; - hcl_oow_t actual_size; - - flags = MAP_PRIVATE | MAP_ANONYMOUS; - - #if defined(MAP_HUGETLB) - flags |= MAP_HUGETLB; - #endif - - #if defined(MAP_UNINITIALIZED) - flags |= MAP_UNINITIALIZED; - #endif - - actual_size = HCL_SIZEOF(hcl_oow_t) + size; - actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024); - ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ptr == MAP_FAILED) - { - #if defined(MAP_HUGETLB) - flags &= ~MAP_HUGETLB; - ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ptr == MAP_FAILED) return HCL_NULL; - #else - return HCL_NULL; - #endif - } - *ptr = actual_size; - - return (void*)(ptr + 1); - -#else - return HCL_MMGR_ALLOC(hcl->mmgr, size); -#endif -} - -static void free_heap (hcl_t* hcl, void* ptr) -{ -#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) - hcl_oow_t* actual_ptr; - actual_ptr = (hcl_oow_t*)ptr - 1; - munmap (actual_ptr, *actual_ptr); -#else - return HCL_MMGR_FREE(hcl->mmgr, ptr); -#endif -} - static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len) { while (len > 0) @@ -772,634 +699,34 @@ static void log_write (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hc flush_log (hcl, logfd); } - -static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len) -{ -#if defined(HAVE_STRERROR_R) - strerror_r (syserr, buf, len); -#else - /* this may not be thread safe */ - hcl_copy_bcstr (buf, len, strerror(syserr)); -#endif -} - -/* ========================================================================= */ -#if defined(USE_MACH_O_DYLD) -static const char* mach_dlerror_str = ""; - -static void* mach_dlopen (const char* path) -{ - NSObjectFileImage image; - NSObjectFileImageReturnCode rc; - void* handle; - - mach_dlerror_str = ""; - if ((rc = NSCreateObjectFileImageFromFile(path, &image)) != NSObjectFileImageSuccess) - { - switch (rc) - { - case NSObjectFileImageFailure: - case NSObjectFileImageFormat: - mach_dlerror_str = "unable to crate object file image"; - break; - - case NSObjectFileImageInappropriateFile: - mach_dlerror_str = "inappropriate file"; - break; - - case NSObjectFileImageArch: - mach_dlerror_str = "incompatible architecture"; - break; - - case NSObjectFileImageAccess: - mach_dlerror_str = "inaccessible file"; - break; - - default: - mach_dlerror_str = "unknown error"; - break; - } - return HCL_NULL; - } - handle = (void*)NSLinkModule(image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); - NSDestroyObjectFileImage (image); - return handle; -} - -static HCL_INLINE void mach_dlclose (void* handle) -{ - mach_dlerror_str = ""; - NSUnLinkModule (handle, NSUNLINKMODULE_OPTION_NONE); -} - -static HCL_INLINE void* mach_dlsym (void* handle, const char* name) -{ - mach_dlerror_str = ""; - return (void*)NSAddressOfSymbol(NSLookupSymbolInModule(handle, name)); -} - -static const char* mach_dlerror (void) -{ - int err_no; - const char* err_file; - NSLinkEditErrors err; - - if (mach_dlerror_str[0] == '\0') - NSLinkEditError (&err, &err_no, &err_file, &mach_dlerror_str); - - return mach_dlerror_str; -} -#endif - -static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - hcl_bch_t stabuf[128], * bufptr; - hcl_oow_t ucslen, bcslen, bufcapa; - void* handle; - - #if defined(HCL_OOCH_IS_UCH) - if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bufcapa) <= -1) return HCL_NULL; - /* +1 for terminating null. but it's not needed because HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) - * and HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTIFX) include the terminating nulls. Never mind about - * the extra 2 characters. */ - #else - bufcapa = hcl_count_bcstr(name); - #endif - bufcapa += HCL_COUNTOF(HCL_DEFAULT_PFMODDIR) + HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTFIX) + 1; - - if (bufcapa <= HCL_COUNTOF(stabuf)) bufptr = stabuf; - else - { - bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); - if (!bufptr) return HCL_NULL; - } - - if (flags & HCL_VMPRIM_DLOPEN_PFMOD) - { - hcl_oow_t len, i, xlen, dlen; - - /* opening a primitive function module - mostly libhcl-xxxx. - * if PFMODPREFIX is absolute, never use PFMODDIR */ - dlen = IS_PATH_ABSOLUTE(HCL_DEFAULT_PFMODPREFIX)? - 0: hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODDIR); - len = hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODPREFIX); - len += dlen; - - bcslen = bufcapa - len; - #if defined(HCL_OOCH_IS_UCH) - hcl_convootobcstr(hcl, name, &ucslen, &bufptr[len], &bcslen); - #else - bcslen = hcl_copy_bcstr(&bufptr[len], bcslen, name); - #endif - - /* length including the directory, the prefix and the name. but excluding the postfix */ - xlen = len + bcslen; - - for (i = len; i < xlen; i++) - { - /* convert a period(.) to a dash(-) */ - if (bufptr[i] == '.') bufptr[i] = '-'; - } - - retry: - hcl_copy_bcstr (&bufptr[xlen], bufcapa - xlen, HCL_DEFAULT_PFMODPOSTFIX); - - /* both prefix and postfix attached. for instance, libhcl-xxx */ - handle = sys_dl_openext(bufptr); - if (!handle) - { - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[dlen], name, sys_dl_error()); - - if (dlen > 0) - { - handle = sys_dl_openext(&bufptr[0]); - if (handle) goto pfmod_open_ok; - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[0], name, sys_dl_error()); - } - - /* try without prefix and postfix */ - bufptr[xlen] = '\0'; - handle = sys_dl_openext(&bufptr[len]); - if (!handle) - { - hcl_bch_t* dash; - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) PFMOD %js - %hs", name, dl_errstr); - - dash = hcl_rfind_bchar(bufptr, hcl_count_bcstr(bufptr), '-'); - if (dash) - { - /* remove a segment at the back. - * [NOTE] a dash contained in the original name before - * period-to-dash transformation may cause extraneous/wrong - * loading reattempts. */ - xlen = dash - bufptr; - goto retry; - } - } - else - { - HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[len], name, handle); - } - } - else - { - pfmod_open_ok: - HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[dlen], name, handle); - } - } - else - { - /* opening a raw shared object without a prefix and/or a postfix */ - #if defined(HCL_OOCH_IS_UCH) - bcslen = bufcapa; - hcl_convootobcstr(hcl, name, &ucslen, bufptr, &bcslen); - #else - bcslen = hcl_copy_bcstr(bufptr, bufcapa, name); - #endif - - if (hcl_find_bchar(bufptr, bcslen, '.')) - { - handle = sys_dl_open(bufptr); - if (!handle) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG2 (hcl, "Unable to open DL %hs - %hs\n", bufptr, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, dl_errstr); - } - else HCL_DEBUG2 (hcl, "Opened DL %hs handle %p\n", bufptr, handle); - } - else - { - handle = sys_dl_openext(bufptr); - if (!handle) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG2 (hcl, "Unable to open(ext) DL %hs - %s\n", bufptr, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr); - } - else HCL_DEBUG2 (hcl, "Opened(ext) DL %hs handle %p\n", bufptr, handle); - } - } - - if (bufptr != stabuf) hcl_freemem (hcl, bufptr); - return handle; - -#else - -/* TODO: support various platforms */ - /* TODO: implemenent this */ - HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot open %js\n", name); - hcl_seterrbfmt (hcl, HCL_ENOIMPL, "dynamic loading not implemented - cannot open %js", name); - return HCL_NULL; -#endif -} - -static void dl_close (hcl_t* hcl, void* handle) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - HCL_DEBUG1 (hcl, "Closed DL handle %p\n", handle); - sys_dl_close (handle); - -#else - /* TODO: implemenent this */ - HCL_DEBUG1 (hcl, "Dynamic loading not implemented - cannot close handle %p\n", handle); -#endif -} - -static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name) -{ -#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O_DYLD) - hcl_bch_t stabuf[64], * bufptr; - hcl_oow_t bufcapa, ucslen, bcslen, i; - const hcl_bch_t* symname; - void* sym; - - #if defined(HCL_OOCH_IS_UCH) - if (hcl_convootobcstr(hcl, name, &ucslen, HCL_NULL, &bcslen) <= -1) return HCL_NULL; - #else - bcslen = hcl_count_bcstr (name); - #endif - - if (bcslen >= HCL_COUNTOF(stabuf) - 2) - { - bufcapa = bcslen + 3; - bufptr = (hcl_bch_t*)hcl_allocmem(hcl, bufcapa * HCL_SIZEOF(*bufptr)); - if (!bufptr) return HCL_NULL; - } - else - { - bufcapa = HCL_COUNTOF(stabuf); - bufptr = stabuf; - } - - bcslen = bufcapa - 1; - #if defined(HCL_OOCH_IS_UCH) - hcl_convootobcstr (hcl, name, &ucslen, &bufptr[1], &bcslen); - #else - bcslen = hcl_copy_bcstr(&bufptr[1], bcslen, name); - #endif - - /* convert a period(.) to an underscore(_) */ - for (i = 1; i <= bcslen; i++) if (bufptr[i] == '.') bufptr[i] = '_'; - - symname = &bufptr[1]; /* try the name as it is */ - - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - bufptr[0] = '_'; - symname = &bufptr[0]; /* try _name */ - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - bufptr[bcslen + 1] = '_'; - bufptr[bcslen + 2] = '\0'; - - symname = &bufptr[1]; /* try name_ */ - sym = sys_dl_getsym(handle, symname); - - if (!sym) - { - symname = &bufptr[0]; /* try _name_ */ - sym = sys_dl_getsym(handle, symname); - if (!sym) - { - const hcl_bch_t* dl_errstr; - dl_errstr = sys_dl_error(); - HCL_DEBUG3 (hcl, "Failed to get module symbol %js from handle %p - %hs\n", name, handle, dl_errstr); - hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to get module symbol %hs - %hs", symname, dl_errstr); - - } - } - } - } - - if (sym) HCL_DEBUG3 (hcl, "Loaded module symbol %js from handle %p - %hs\n", name, handle, symname); - if (bufptr != stabuf) hcl_freemem (hcl, bufptr); - return sym; - -#else - /* TODO: IMPLEMENT THIS */ - HCL_DEBUG2 (hcl, "Dynamic loading not implemented - Cannot load module symbol %js from handle %p\n", name, handle); - hcl_seterrbfmt (hcl, HCL_ENOIMPL, "dynamic loading not implemented - Cannot load module symbol %js from handle %p", name, handle); - return HCL_NULL; -#endif -} - -/* ========================================================================= */ - -static void vm_gettime (hcl_t* hcl, hcl_ntime_t* now) -{ -#if defined(_WIN32) - /* TODO: */ -#elif defined(__OS2__) - ULONG out; - -/* TODO: handle overflow?? */ -/* TODO: use DosTmrQueryTime() and DosTmrQueryFreq()? */ - DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, &out, HCL_SIZEOF(out)); /* milliseconds */ - /* it must return NO_ERROR */ - HCL_INITNTIME (now, HCL_MSEC_TO_SEC(out), HCL_MSEC_TO_NSEC(out)); -#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) - clock_t c; - -/* TODO: handle overflow?? */ - c = clock (); - now->sec = c / CLOCKS_PER_SEC; - #if (CLOCKS_PER_SEC == 100) - now->nsec = HCL_MSEC_TO_NSEC((c % CLOCKS_PER_SEC) * 10); - #elif (CLOCKS_PER_SEC == 1000) - now->nsec = HCL_MSEC_TO_NSEC(c % CLOCKS_PER_SEC); - #elif (CLOCKS_PER_SEC == 1000000L) - now->nsec = HCL_USEC_TO_NSEC(c % CLOCKS_PER_SEC); - #elif (CLOCKS_PER_SEC == 1000000000L) - now->nsec = (c % CLOCKS_PER_SEC); - #else - # error UNSUPPORTED CLOCKS_PER_SEC - #endif -#elif defined(macintosh) - UnsignedWide tick; - hcl_uint64_t tick64; - Microseconds (&tick); - tick64 = *(hcl_uint64_t*)&tick; - HCL_INITNTIME (now, HCL_USEC_TO_SEC(tick64), HCL_USEC_TO_NSEC(tick64)); -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) - struct timespec ts; - clock_gettime (CLOCK_MONOTONIC, &ts); - HCL_INITNTIME(now, ts.tv_sec, ts.tv_nsec); -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) - struct timespec ts; - clock_gettime (CLOCK_REALTIME, &ts); - HCL_INITNTIME(now, ts.tv_sec, ts.tv_nsec); -#else - struct timeval tv; - gettimeofday (&tv, HCL_NULL); - HCL_INITNTIME(now, tv.tv_sec, HCL_USEC_TO_NSEC(tv.tv_usec)); -#endif -} - -static void vm_sleep (hcl_t* hcl, const hcl_ntime_t* dur) -{ -#if defined(_WIN32) - xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); - if (xtn->waitable_timer) - { - LARGE_INTEGER li; - li.QuadPart = -HCL_SECNSEC_TO_NSEC(dur->sec, dur->nsec); - if(SetWaitableTimer(xtn->waitable_timer, &li, 0, HCL_NULL, HCL_NULL, FALSE) == FALSE) goto normal_sleep; - WaitForSingleObject(xtn->waitable_timer, INFINITE); - } - else - { - normal_sleep: - /* fallback to normal Sleep() */ - Sleep (HCL_SECNSEC_TO_MSEC(dur->sec,dur->nsec)); - } -#elif defined(__OS2__) - - /* TODO: in gui mode, this is not a desirable method??? - * this must be made event-driven coupled with the main event loop */ - DosSleep (HCL_SECNSEC_TO_MSEC(dur->sec,dur->nsec)); - -#elif defined(macintosh) - - /* TODO: ... */ - -#elif defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) - - clock_t c; - - c = clock (); - c += dur->sec * CLOCKS_PER_SEC; - - #if (CLOCKS_PER_SEC == 100) - c += HCL_NSEC_TO_MSEC(dur->nsec) / 10; - #elif (CLOCKS_PER_SEC == 1000) - c += HCL_NSEC_TO_MSEC(dur->nsec); - #elif (CLOCKS_PER_SEC == 1000000L) - c += HCL_NSEC_TO_USEC(dur->nsec); - #elif (CLOCKS_PER_SEC == 1000000000L) - c += dur->nsec; - #else - # error UNSUPPORTED CLOCKS_PER_SEC - #endif - -/* TODO: handle clock overvlow */ -/* TODO: check if there is abortion request or interrupt */ - while (c > clock()) - { - _halt_cpu(); - } - -#else - #if defined(USE_THREAD) - /* the sleep callback is called only if there is no IO semaphore - * waiting. so i can safely call vm_muxwait() without a muxwait callback - * when USE_THREAD is true */ - vm_muxwait (hcl, dur, HCL_NULL); - #elif defined(HAVE_NANOSLEEP) - struct timespec ts; - ts.tv_sec = dur->sec; - ts.tv_nsec = dur->nsec; - nanosleep (&ts, HCL_NULL); - #elif defined(HAVE_USLEEP) - usleep (HCL_SECNSEC_TO_USEC(dur->sec, dur->nsec)); - #else - # error UNSUPPORT SLEEP - #endif -#endif -} +#include "cb-impl.h" /* ========================================================================= */ static int vm_startup (hcl_t* hcl) { + xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + #if defined(_WIN32) - xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); xtn->waitable_timer = CreateWaitableTimer(HCL_NULL, TRUE, HCL_NULL); - xtn->vm_running = 1; - return 0; -#else - - xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); - int pcount = 0, flag; - -#if defined(USE_DEVPOLL) - xtn->ep = open ("/dev/poll", O_RDWR); - if (xtn->ep == -1) - { - hcl_syserr_to_errnum (errno); - HCL_DEBUG1 (hcl, "Cannot create devpoll - %hs\n", strerror(errno)); - goto oops; - } - - flag = fcntl (xtn->ep, F_GETFD); - if (flag >= 0) fcntl (xtn->ep, F_SETFD, flag | FD_CLOEXEC); - -#elif defined(USE_EPOLL) - #if defined(EPOLL_CLOEXEC) - xtn->ep = epoll_create1 (EPOLL_CLOEXEC); - #else - xtn->ep = epoll_create (1024); - #endif - if (xtn->ep == -1) - { - hcl_syserr_to_errnum (errno); - HCL_DEBUG1 (hcl, "Cannot create epoll - %hs\n", strerror(errno)); - goto oops; - } - - #if defined(EPOLL_CLOEXEC) - /* do nothing */ - #else - flag = fcntl (xtn->ep, F_GETFD); - if (flag >= 0) fcntl (xtn->ep, F_SETFD, flag | FD_CLOEXEC); - #endif - -#elif defined(USE_POLL) - - MUTEX_INIT (&xtn->ev.reg.pmtx); - -#elif defined(USE_SELECT) - FD_ZERO (&xtn->ev.reg.rfds); - FD_ZERO (&xtn->ev.reg.wfds); - xtn->ev.reg.maxfd = -1; - MUTEX_INIT (&xtn->ev.reg.smtx); -#endif /* USE_DEVPOLL */ - -#if defined(USE_THREAD) - if (pipe(xtn->p) == -1) - { - hcl_syserr_to_errnum (errno); - HCL_DEBUG1 (hcl, "Cannot create pipes - %hs\n", strerror(errno)); - goto oops; - } - pcount = 2; - - #if defined(O_CLOEXEC) - flag = fcntl (xtn->p[0], F_GETFD); - if (flag >= 0) fcntl (xtn->p[0], F_SETFD, flag | FD_CLOEXEC); - flag = fcntl (xtn->p[1], F_GETFD); - if (flag >= 0) fcntl (xtn->p[1], F_SETFD, flag | FD_CLOEXEC); - #endif - - #if defined(O_NONBLOCK) - flag = fcntl (xtn->p[0], F_GETFL); - if (flag >= 0) fcntl (xtn->p[0], F_SETFL, flag | O_NONBLOCK); - flag = fcntl (xtn->p[1], F_GETFL); - if (flag >= 0) fcntl (xtn->p[1], F_SETFL, flag | O_NONBLOCK); - #endif - - if (_add_poll_fd(hcl, xtn->p[0], XPOLLIN) <= -1) goto oops; - - pthread_mutex_init (&xtn->ev.mtx, HCL_NULL); - pthread_cond_init (&xtn->ev.cnd, HCL_NULL); - pthread_cond_init (&xtn->ev.cnd2, HCL_NULL); - - xtn->iothr_abort = 0; - xtn->iothr_up = 0; - /*pthread_create (&xtn->iothr, HCL_NULL, iothr_main, hcl);*/ - -#endif /* USE_THREAD */ +#endif xtn->vm_running = 1; return 0; - -oops: - -#if defined(USE_THREAD) - if (pcount > 0) - { - close (xtn->p[0]); - close (xtn->p[1]); - } -#endif - -#if defined(USE_DEVPOLL) || defined(USE_EPOLL) - if (xtn->ep >= 0) - { - close (xtn->ep); - xtn->ep = -1; - } -#endif - - return -1; -#endif } static void vm_cleanup (hcl_t* hcl) { -#if defined(_WIN32) xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); + + xtn->vm_running = 0; + +#if defined(_WIN32) if (xtn->waitable_timer) { CloseHandle (xtn->waitable_timer); xtn->waitable_timer = HCL_NULL; } -#else - xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); - - xtn->vm_running = 0; - -#if defined(USE_THREAD) - if (xtn->iothr_up) - { - xtn->iothr_abort = 1; - write (xtn->p[1], "Q", 1); - pthread_cond_signal (&xtn->ev.cnd); - pthread_join (xtn->iothr, HCL_NULL); - xtn->iothr_up = 0; - } - pthread_cond_destroy (&xtn->ev.cnd); - pthread_cond_destroy (&xtn->ev.cnd2); - pthread_mutex_destroy (&xtn->ev.mtx); - - _del_poll_fd (hcl, xtn->p[0]); - close (xtn->p[1]); - close (xtn->p[0]); -#endif /* USE_THREAD */ - -#if defined(USE_DEVPOLL) - if (xtn->ep >= 0) - { - close (xtn->ep); - xtn->ep = -1; - } - /*destroy_poll_data_space (hcl);*/ -#elif defined(USE_EPOLL) - if (xtn->ep >= 0) - { - close (xtn->ep); - xtn->ep = -1; - } -#elif defined(USE_POLL) - if (xtn->ev.reg.ptr) - { - hcl_freemem (hcl, xtn->ev.reg.ptr); - xtn->ev.reg.ptr = HCL_NULL; - xtn->ev.reg.len = 0; - xtn->ev.reg.capa = 0; - } - if (xtn->ev.buf) - { - hcl_freemem (hcl, xtn->ev.buf); - xtn->ev.buf = HCL_NULL; - } - /*destroy_poll_data_space (hcl);*/ - MUTEX_DESTROY (&xtn->ev.reg.pmtx); -#elif defined(USE_SELECT) - FD_ZERO (&xtn->ev.reg.rfds); - FD_ZERO (&xtn->ev.reg.wfds); - xtn->ev.reg.maxfd = -1; - MUTEX_DESTROY (&xtn->ev.reg.smtx); -#endif - #endif } diff --git a/lib/tmr.c b/lib/tmr.c index 44b94a1..23ebc3a 100644 --- a/lib/tmr.c +++ b/lib/tmr.c @@ -31,7 +31,7 @@ #define HEAP_LEFT(x) ((x) * 2 + 1) #define HEAP_RIGHT(x) ((x) * 2 + 2) -#define YOUNGER_THAN(x,y) (HCL_CMPNTIME(&(x)->when, &(y)->when) < 0) +#define YOUNGER_THAN(x,y) (HCL_CMP_NTIME(&(x)->when, &(y)->when) < 0) hcl_tmr_t* hcl_tmr_open (hcl_t* hcl, hcl_oow_t xtnsize, hcl_oow_t capa) { @@ -248,7 +248,7 @@ int hcl_tmr_fire (hcl_tmr_t* tmr, const hcl_ntime_t* tm, hcl_oow_t* firecnt) while (tmr->size > 0) { - if (HCL_CMPNTIME(&tmr->event[0].when, &now) > 0) break; + if (HCL_CMP_NTIME(&tmr->event[0].when, &now) > 0) break; event = tmr->event[0]; hcl_tmr_delete (tmr, 0); /* remove the registered event structure */ @@ -273,8 +273,8 @@ int hcl_tmr_gettmout (hcl_tmr_t* tmr, const hcl_ntime_t* tm, hcl_ntime_t* tmout) /*else if (hcl_gettime(&now) <= -1) return -1;*/ tmr->hcl->vmprim.vm_gettime (tmr->hcl, &now); - HCL_SUBNTIME (tmout, &tmr->event[0].when, &now); - if (tmout->sec < 0) HCL_CLEARNTIME (tmout); + HCL_SUB_NTIME (tmout, &tmr->event[0].when, &now); + if (tmout->sec < 0) HCL_CLEAR_NTIME (tmout); return 0; }