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:
Matthew Flatt 2011-09-16 16:18:10 -06:00
parent 33831cbd8a
commit b79c410e5b
4 changed files with 67 additions and 45 deletions

View File

@ -333,6 +333,7 @@ typedef struct Thread_Local_Variables {
struct Scheme_Hash_Table *fullpath_loaded_extensions_;
Scheme_Sleep_Proc scheme_place_sleep_;
struct Scheme_Bucket_Table *taint_intern_table_;
struct GHBN_Thread_Data *ghbn_thread_data_;
} Thread_Local_Variables;
#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 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 ghbn_thread_data XOA (scheme_get_thread_local_variables()->ghbn_thread_data_)
/* **************************************** */

View File

@ -555,6 +555,7 @@ void scheme_place_instance_destroy(int force)
GC_destruct_child_gc();
#endif
scheme_free_all_code();
scheme_free_ghbn_data();
}
static void make_kernel_env(void)

View File

@ -313,7 +313,7 @@ typedef struct SOCKADDR_IN mz_unspec_address;
/******************************* hostnames ************************************/
#ifdef OS_X
#if defined(OS_X) || defined(USE_PTHREAD_THREAD_TIMER)
# define PTHREADS_OK_FOR_GHBN
#endif
@ -413,8 +413,6 @@ const char *mz_gai_strerror(int ecode)
# define MZ_LPTHREAD_START_ROUTINE void *(*)(void *)
# endif
static volatile int ghbn_lock;
typedef struct {
# ifdef USE_WINSOCK_TCP
HANDLE th;
@ -426,43 +424,48 @@ typedef struct {
int done;
} GHBN_Rec;
static struct mz_addrinfo * volatile ghbn_result;
static volatile int ghbn_err;
/* For in-thread DNS: */
#define MZ_MAX_HOSTNAME_LEN 128
#define MZ_MAX_SERVNAME_LEN 32
static char ghbn_hostname[MZ_MAX_HOSTNAME_LEN];
static char ghbn_servname[MZ_MAX_SERVNAME_LEN];
static struct mz_addrinfo ghbn_hints;
typedef struct GHBN_Thread_Data {
int ghbn_lock;
char ghbn_hostname[MZ_MAX_HOSTNAME_LEN];
char ghbn_servname[MZ_MAX_SERVNAME_LEN];
struct mz_addrinfo ghbn_hints;
# ifdef USE_WINSOCK_TCP
HANDLE ready_sema;
HANDLE ready_sema;
# else
int ready_fd;
int ready_fd;
# 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
{
GHBN_Thread_Data *data = (GHBN_Thread_Data *)_data;
int ok;
struct mz_addrinfo *res, hints;
char hn_copy[MZ_MAX_HOSTNAME_LEN], sn_copy[MZ_MAX_SERVNAME_LEN];
# ifndef USE_WINSOCK_TCP
int fd = ready_fd;
int fd = data->ready_fd;
# endif
if (ghbn_result) {
mz_freeaddrinfo(ghbn_result);
ghbn_result = NULL;
if (data->ghbn_result) {
mz_freeaddrinfo(data->ghbn_result);
data->ghbn_result = NULL;
}
strcpy(hn_copy, ghbn_hostname);
strcpy(sn_copy, ghbn_servname);
memcpy(&hints, &ghbn_hints, sizeof(hints));
strcpy(hn_copy, data->ghbn_hostname);
strcpy(sn_copy, data->ghbn_servname);
memcpy(&hints, &data->ghbn_hints, sizeof(hints));
# ifdef USE_WINSOCK_TCP
ReleaseSemaphore(ready_sema, 1, NULL);
ReleaseSemaphore(data->ready_sema, 1, NULL);
# else
write(fd, "?", 1);
# endif
@ -471,8 +474,8 @@ static intptr_t getaddrinfo_in_thread(void *data)
sn_copy[0] ? sn_copy : NULL,
&hints, &res);
ghbn_result = res;
ghbn_err = ok;
data->ghbn_result = res;
data->ghbn_err = ok;
# ifndef USE_WINSOCK_TCP
{
@ -487,7 +490,7 @@ static intptr_t getaddrinfo_in_thread(void *data)
static void release_ghbn_lock(GHBN_Rec *rec)
{
ghbn_lock = 0;
ghbn_thread_data->ghbn_lock = 0;
# ifdef USE_WINSOCK_TCP
CloseHandle(rec->th);
# else
@ -497,7 +500,7 @@ static void release_ghbn_lock(GHBN_Rec *rec)
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)
@ -509,9 +512,9 @@ static int ghbn_thread_done(Scheme_Object *_rec)
# ifdef USE_WINSOCK_TCP
if (WaitForSingleObject(rec->th, 0) == WAIT_OBJECT_0) {
rec->result = ghbn_result;
ghbn_result = NULL;
rec->err = ghbn_err;
rec->result = ghbn_thread_data->ghbn_result;
ghbn_thread_data->ghbn_result = NULL;
rec->err = ghbn_thread_data->ghbn_err;
rec->done = 1;
return 1;
}
@ -519,9 +522,9 @@ static int ghbn_thread_done(Scheme_Object *_rec)
{
long v;
if (read(rec->pin, &v, sizeof(long)) > 0) {
rec->result = ghbn_result;
ghbn_result = NULL;
rec->err = ghbn_err;
rec->result = ghbn_thread_data->ghbn_result;
ghbn_thread_data->ghbn_result = NULL;
rec->err = ghbn_thread_data->ghbn_err;
rec->done = 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);
}
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->done = 0;
scheme_block_until(ghbn_lock_avail, NULL, NULL, 0);
ghbn_lock = 1;
ghbn_thread_data->ghbn_lock = 1;
if (name)
strcpy(ghbn_hostname, name);
strcpy(ghbn_thread_data->ghbn_hostname, name);
else
ghbn_hostname[0] = 0;
ghbn_thread_data->ghbn_hostname[0] = 0;
if (svc)
strcpy(ghbn_servname, svc);
strcpy(ghbn_thread_data->ghbn_servname, svc);
else
ghbn_servname[0] = 0;
memcpy(&ghbn_hints, hints, sizeof(ghbn_hints));
ghbn_thread_data->ghbn_servname[0] = 0;
memcpy(&ghbn_thread_data->ghbn_hints, hints, sizeof(*hints));
# ifdef USE_WINSOCK_TCP
{
HANDLE ready_sema;
DWORD id;
intptr_t th;
ready_sema = CreateSemaphore(NULL, 0, 1, NULL);
ghbn_thread_data->ready_sema = ready_sema;
th = _beginthreadex(NULL, 5000,
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
NULL, 0, &id);
WaitForSingleObject(ready_sema, INFINITE);
CloseHandle(ready_sema);
ghbn_thread_data, 0, &id);
WaitForSingleObject(ghbn_thread_data->ready_sema, INFINITE);
CloseHandle(ghbn_thread_data->ready_sema);
rec->th = (HANDLE)th;
ok = 1;
@ -600,10 +610,10 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
} else {
pthread_t t;
rec->pin = p[0];
ready_fd = p[1];
ghbn_thread_data->ready_fd = p[1];
if (pthread_create(&t, NULL,
(MZ_LPTHREAD_START_ROUTINE)getaddrinfo_in_thread,
NULL)) {
ghbn_thread_data)) {
close(p[0]);
close(p[1]);
ok = 0;
@ -618,9 +628,9 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
if (!ok) {
getaddrinfo_in_thread(rec);
rec->result = ghbn_result;
ghbn_result = NULL;
rec->err = ghbn_err;
rec->result = ghbn_thread_data->ghbn_result;
ghbn_thread_data->ghbn_result = NULL;
rec->err = ghbn_thread_data->ghbn_err;
}
}
# endif
@ -637,14 +647,22 @@ static int MZ_GETADDRINFO(const char *name, const char *svc, struct mz_addrinfo
# endif
}
ghbn_lock = 0;
ghbn_thread_data->ghbn_lock = 0;
*res = rec->result;
return rec->err;
}
void scheme_free_ghbn_data() {
if (ghbn_thread_data) {
free(ghbn_thread_data);
ghbn_thread_data = NULL;
}
}
#else
# define MZ_GETADDRINFO mz_getaddrinfo
void scheme_free_ghbn_data() { }
#endif
#ifdef USE_SOCKETS_TCP

View File

@ -294,6 +294,7 @@ void register_network_evts();
void scheme_free_dynamic_extensions(void);
void scheme_free_all_code(void);
void scheme_free_ghbn_data(void);
XFORM_NONGCING int scheme_is_multiprocessor(int now);