fix in-thread gethostbyname() for places
Uncovered by "place-parallel.rkt" test; not found in previous runs because in-thread gethostbyname() wasn't enabled for Linux, but it is now.
This commit is contained in:
parent
33831cbd8a
commit
b79c410e5b
|
@ -333,6 +333,7 @@ typedef struct Thread_Local_Variables {
|
||||||
struct Scheme_Hash_Table *fullpath_loaded_extensions_;
|
struct Scheme_Hash_Table *fullpath_loaded_extensions_;
|
||||||
Scheme_Sleep_Proc scheme_place_sleep_;
|
Scheme_Sleep_Proc scheme_place_sleep_;
|
||||||
struct Scheme_Bucket_Table *taint_intern_table_;
|
struct Scheme_Bucket_Table *taint_intern_table_;
|
||||||
|
struct GHBN_Thread_Data *ghbn_thread_data_;
|
||||||
} Thread_Local_Variables;
|
} Thread_Local_Variables;
|
||||||
|
|
||||||
#if defined(IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS)
|
#if defined(IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS)
|
||||||
|
@ -667,6 +668,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
|
||||||
#define fullpath_loaded_extensions XOA (scheme_get_thread_local_variables()->fullpath_loaded_extensions_)
|
#define fullpath_loaded_extensions XOA (scheme_get_thread_local_variables()->fullpath_loaded_extensions_)
|
||||||
#define scheme_place_sleep XOA (scheme_get_thread_local_variables()->scheme_place_sleep_)
|
#define scheme_place_sleep XOA (scheme_get_thread_local_variables()->scheme_place_sleep_)
|
||||||
#define taint_intern_table XOA (scheme_get_thread_local_variables()->taint_intern_table_)
|
#define taint_intern_table XOA (scheme_get_thread_local_variables()->taint_intern_table_)
|
||||||
|
#define ghbn_thread_data XOA (scheme_get_thread_local_variables()->ghbn_thread_data_)
|
||||||
|
|
||||||
/* **************************************** */
|
/* **************************************** */
|
||||||
|
|
||||||
|
|
|
@ -555,6 +555,7 @@ void scheme_place_instance_destroy(int force)
|
||||||
GC_destruct_child_gc();
|
GC_destruct_child_gc();
|
||||||
#endif
|
#endif
|
||||||
scheme_free_all_code();
|
scheme_free_all_code();
|
||||||
|
scheme_free_ghbn_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_kernel_env(void)
|
static void make_kernel_env(void)
|
||||||
|
|
|
@ -313,7 +313,7 @@ typedef struct SOCKADDR_IN mz_unspec_address;
|
||||||
|
|
||||||
/******************************* hostnames ************************************/
|
/******************************* hostnames ************************************/
|
||||||
|
|
||||||
#ifdef OS_X
|
#if defined(OS_X) || defined(USE_PTHREAD_THREAD_TIMER)
|
||||||
# define PTHREADS_OK_FOR_GHBN
|
# define PTHREADS_OK_FOR_GHBN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -413,8 +413,6 @@ const char *mz_gai_strerror(int ecode)
|
||||||
# define MZ_LPTHREAD_START_ROUTINE void *(*)(void *)
|
# define MZ_LPTHREAD_START_ROUTINE void *(*)(void *)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
static volatile int ghbn_lock;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
HANDLE th;
|
HANDLE th;
|
||||||
|
@ -426,43 +424,48 @@ typedef struct {
|
||||||
int done;
|
int done;
|
||||||
} GHBN_Rec;
|
} GHBN_Rec;
|
||||||
|
|
||||||
static struct mz_addrinfo * volatile ghbn_result;
|
|
||||||
static volatile int ghbn_err;
|
|
||||||
|
|
||||||
/* For in-thread DNS: */
|
/* For in-thread DNS: */
|
||||||
#define MZ_MAX_HOSTNAME_LEN 128
|
#define MZ_MAX_HOSTNAME_LEN 128
|
||||||
#define MZ_MAX_SERVNAME_LEN 32
|
#define MZ_MAX_SERVNAME_LEN 32
|
||||||
|
|
||||||
static char ghbn_hostname[MZ_MAX_HOSTNAME_LEN];
|
typedef struct GHBN_Thread_Data {
|
||||||
static char ghbn_servname[MZ_MAX_SERVNAME_LEN];
|
int ghbn_lock;
|
||||||
static struct mz_addrinfo ghbn_hints;
|
char ghbn_hostname[MZ_MAX_HOSTNAME_LEN];
|
||||||
|
char ghbn_servname[MZ_MAX_SERVNAME_LEN];
|
||||||
|
struct mz_addrinfo ghbn_hints;
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
HANDLE ready_sema;
|
HANDLE ready_sema;
|
||||||
# else
|
# else
|
||||||
int ready_fd;
|
int ready_fd;
|
||||||
# endif
|
# endif
|
||||||
|
struct mz_addrinfo *ghbn_result;
|
||||||
|
int ghbn_err;
|
||||||
|
} GHBN_Thread_Data;
|
||||||
|
|
||||||
static intptr_t getaddrinfo_in_thread(void *data)
|
THREAD_LOCAL_DECL(GHBN_Thread_Data *ghbn_thread_data);
|
||||||
|
|
||||||
|
static intptr_t getaddrinfo_in_thread(void *_data)
|
||||||
XFORM_SKIP_PROC
|
XFORM_SKIP_PROC
|
||||||
{
|
{
|
||||||
|
GHBN_Thread_Data *data = (GHBN_Thread_Data *)_data;
|
||||||
int ok;
|
int ok;
|
||||||
struct mz_addrinfo *res, hints;
|
struct mz_addrinfo *res, hints;
|
||||||
char hn_copy[MZ_MAX_HOSTNAME_LEN], sn_copy[MZ_MAX_SERVNAME_LEN];
|
char hn_copy[MZ_MAX_HOSTNAME_LEN], sn_copy[MZ_MAX_SERVNAME_LEN];
|
||||||
# ifndef USE_WINSOCK_TCP
|
# ifndef USE_WINSOCK_TCP
|
||||||
int fd = ready_fd;
|
int fd = data->ready_fd;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (ghbn_result) {
|
if (data->ghbn_result) {
|
||||||
mz_freeaddrinfo(ghbn_result);
|
mz_freeaddrinfo(data->ghbn_result);
|
||||||
ghbn_result = NULL;
|
data->ghbn_result = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(hn_copy, ghbn_hostname);
|
strcpy(hn_copy, data->ghbn_hostname);
|
||||||
strcpy(sn_copy, ghbn_servname);
|
strcpy(sn_copy, data->ghbn_servname);
|
||||||
memcpy(&hints, &ghbn_hints, sizeof(hints));
|
memcpy(&hints, &data->ghbn_hints, sizeof(hints));
|
||||||
|
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
ReleaseSemaphore(ready_sema, 1, NULL);
|
ReleaseSemaphore(data->ready_sema, 1, NULL);
|
||||||
# else
|
# else
|
||||||
write(fd, "?", 1);
|
write(fd, "?", 1);
|
||||||
# endif
|
# endif
|
||||||
|
@ -471,8 +474,8 @@ static intptr_t getaddrinfo_in_thread(void *data)
|
||||||
sn_copy[0] ? sn_copy : NULL,
|
sn_copy[0] ? sn_copy : NULL,
|
||||||
&hints, &res);
|
&hints, &res);
|
||||||
|
|
||||||
ghbn_result = res;
|
data->ghbn_result = res;
|
||||||
ghbn_err = ok;
|
data->ghbn_err = ok;
|
||||||
|
|
||||||
# ifndef USE_WINSOCK_TCP
|
# ifndef USE_WINSOCK_TCP
|
||||||
{
|
{
|
||||||
|
@ -487,7 +490,7 @@ static intptr_t getaddrinfo_in_thread(void *data)
|
||||||
|
|
||||||
static void release_ghbn_lock(GHBN_Rec *rec)
|
static void release_ghbn_lock(GHBN_Rec *rec)
|
||||||
{
|
{
|
||||||
ghbn_lock = 0;
|
ghbn_thread_data->ghbn_lock = 0;
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
CloseHandle(rec->th);
|
CloseHandle(rec->th);
|
||||||
# else
|
# else
|
||||||
|
@ -497,7 +500,7 @@ static void release_ghbn_lock(GHBN_Rec *rec)
|
||||||
|
|
||||||
static int ghbn_lock_avail(Scheme_Object *_ignored)
|
static int ghbn_lock_avail(Scheme_Object *_ignored)
|
||||||
{
|
{
|
||||||
return !ghbn_lock;
|
return !ghbn_thread_data->ghbn_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ghbn_thread_done(Scheme_Object *_rec)
|
static int ghbn_thread_done(Scheme_Object *_rec)
|
||||||
|
@ -509,9 +512,9 @@ static int ghbn_thread_done(Scheme_Object *_rec)
|
||||||
|
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
if (WaitForSingleObject(rec->th, 0) == WAIT_OBJECT_0) {
|
if (WaitForSingleObject(rec->th, 0) == WAIT_OBJECT_0) {
|
||||||
rec->result = ghbn_result;
|
rec->result = ghbn_thread_data->ghbn_result;
|
||||||
ghbn_result = NULL;
|
ghbn_thread_data->ghbn_result = NULL;
|
||||||
rec->err = ghbn_err;
|
rec->err = ghbn_thread_data->ghbn_err;
|
||||||
rec->done = 1;
|
rec->done = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -519,9 +522,9 @@ static int ghbn_thread_done(Scheme_Object *_rec)
|
||||||
{
|
{
|
||||||
long v;
|
long v;
|
||||||
if (read(rec->pin, &v, sizeof(long)) > 0) {
|
if (read(rec->pin, &v, sizeof(long)) > 0) {
|
||||||
rec->result = ghbn_result;
|
rec->result = ghbn_thread_data->ghbn_result;
|
||||||
ghbn_result = NULL;
|
ghbn_thread_data->ghbn_result = NULL;
|
||||||
rec->err = ghbn_err;
|
rec->err = ghbn_thread_data->ghbn_err;
|
||||||
rec->done = 1;
|
rec->done = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -560,34 +563,41 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
|
||||||
return mz_getaddrinfo(name, svc, hints, res);
|
return mz_getaddrinfo(name, svc, hints, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ghbn_thread_data) {
|
||||||
|
ghbn_thread_data = (GHBN_Thread_Data *)malloc(sizeof(GHBN_Thread_Data));
|
||||||
|
memset(ghbn_thread_data, 0, sizeof(GHBN_Thread_Data));
|
||||||
|
}
|
||||||
|
|
||||||
rec = MALLOC_ONE_ATOMIC(GHBN_Rec);
|
rec = MALLOC_ONE_ATOMIC(GHBN_Rec);
|
||||||
rec->done = 0;
|
rec->done = 0;
|
||||||
|
|
||||||
scheme_block_until(ghbn_lock_avail, NULL, NULL, 0);
|
scheme_block_until(ghbn_lock_avail, NULL, NULL, 0);
|
||||||
|
|
||||||
ghbn_lock = 1;
|
ghbn_thread_data->ghbn_lock = 1;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
strcpy(ghbn_hostname, name);
|
strcpy(ghbn_thread_data->ghbn_hostname, name);
|
||||||
else
|
else
|
||||||
ghbn_hostname[0] = 0;
|
ghbn_thread_data->ghbn_hostname[0] = 0;
|
||||||
if (svc)
|
if (svc)
|
||||||
strcpy(ghbn_servname, svc);
|
strcpy(ghbn_thread_data->ghbn_servname, svc);
|
||||||
else
|
else
|
||||||
ghbn_servname[0] = 0;
|
ghbn_thread_data->ghbn_servname[0] = 0;
|
||||||
memcpy(&ghbn_hints, hints, sizeof(ghbn_hints));
|
memcpy(&ghbn_thread_data->ghbn_hints, hints, sizeof(*hints));
|
||||||
|
|
||||||
# ifdef USE_WINSOCK_TCP
|
# ifdef USE_WINSOCK_TCP
|
||||||
{
|
{
|
||||||
|
HANDLE ready_sema;
|
||||||
DWORD id;
|
DWORD id;
|
||||||
intptr_t th;
|
intptr_t th;
|
||||||
|
|
||||||
ready_sema = CreateSemaphore(NULL, 0, 1, NULL);
|
ready_sema = CreateSemaphore(NULL, 0, 1, NULL);
|
||||||
|
ghbn_thread_data->ready_sema = ready_sema;
|
||||||
th = _beginthreadex(NULL, 5000,
|
th = _beginthreadex(NULL, 5000,
|
||||||
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
|
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
|
||||||
NULL, 0, &id);
|
ghbn_thread_data, 0, &id);
|
||||||
WaitForSingleObject(ready_sema, INFINITE);
|
WaitForSingleObject(ghbn_thread_data->ready_sema, INFINITE);
|
||||||
CloseHandle(ready_sema);
|
CloseHandle(ghbn_thread_data->ready_sema);
|
||||||
|
|
||||||
rec->th = (HANDLE)th;
|
rec->th = (HANDLE)th;
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
@ -600,10 +610,10 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
|
||||||
} else {
|
} else {
|
||||||
pthread_t t;
|
pthread_t t;
|
||||||
rec->pin = p[0];
|
rec->pin = p[0];
|
||||||
ready_fd = p[1];
|
ghbn_thread_data->ready_fd = p[1];
|
||||||
if (pthread_create(&t, NULL,
|
if (pthread_create(&t, NULL,
|
||||||
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
|
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
|
||||||
NULL)) {
|
ghbn_thread_data)) {
|
||||||
close(p[0]);
|
close(p[0]);
|
||||||
close(p[1]);
|
close(p[1]);
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
@ -618,9 +628,9 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
getaddrinfo_in_thread(rec);
|
getaddrinfo_in_thread(rec);
|
||||||
rec->result = ghbn_result;
|
rec->result = ghbn_thread_data->ghbn_result;
|
||||||
ghbn_result = NULL;
|
ghbn_thread_data->ghbn_result = NULL;
|
||||||
rec->err = ghbn_err;
|
rec->err = ghbn_thread_data->ghbn_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
@ -637,14 +647,22 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ghbn_lock = 0;
|
ghbn_thread_data->ghbn_lock = 0;
|
||||||
|
|
||||||
*res = rec->result;
|
*res = rec->result;
|
||||||
|
|
||||||
return rec->err;
|
return rec->err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scheme_free_ghbn_data() {
|
||||||
|
if (ghbn_thread_data) {
|
||||||
|
free(ghbn_thread_data);
|
||||||
|
ghbn_thread_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
# define MZ_GETADDRINFO mz_getaddrinfo
|
# define MZ_GETADDRINFO mz_getaddrinfo
|
||||||
|
void scheme_free_ghbn_data() { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SOCKETS_TCP
|
#ifdef USE_SOCKETS_TCP
|
||||||
|
|
|
@ -294,6 +294,7 @@ void register_network_evts();
|
||||||
|
|
||||||
void scheme_free_dynamic_extensions(void);
|
void scheme_free_dynamic_extensions(void);
|
||||||
void scheme_free_all_code(void);
|
void scheme_free_all_code(void);
|
||||||
|
void scheme_free_ghbn_data(void);
|
||||||
|
|
||||||
XFORM_NONGCING int scheme_is_multiprocessor(int now);
|
XFORM_NONGCING int scheme_is_multiprocessor(int now);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user