diff options
| author | Eric Andersen <andersen@codepoet.org> | 2005-04-28 18:27:41 +0000 | 
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2005-04-28 18:27:41 +0000 | 
| commit | a4294fd5e12eeb0ec81e06244096d4a00bae01f3 (patch) | |
| tree | a1a54579cbb9f45d6aea4402542196520f36fbea | |
| parent | c1054500dbb6ee49070bddefebedd938dcd7a0f8 (diff) | |
This might actually now be thread safe, assuming I havn't broken it.
| -rw-r--r-- | libc/inet/resolv.c | 47 | 
1 files changed, 27 insertions, 20 deletions
| diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 01e8edf2d..752bf7fc1 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -674,6 +674,7 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  	char *dns, *lookup = malloc(MAXDNAME);  	int variant = -1;  	struct sockaddr_in sa; +	int local_ns, local_id;  #ifdef __UCLIBC_HAS_IPV6__  	int v6;  	struct sockaddr_in6 sa6; @@ -686,10 +687,14 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  	DPRINTF("Looking up type %d answer for '%s'\n", type, name); +	/* Mess with globals while under lock */  	LOCK; -	ns %= nscount; +	local_ns = ns; +	local_id = id;  	UNLOCK; +	local_ns %= nscount; +  	while (retries < MAX_RETRIES) {  		if (fd != -1)  			close(fd); @@ -698,13 +703,10 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  		memset(&h, 0, sizeof(h)); -		/* Mess with globals while under lock */ -		LOCK; -		++id; -		id &= 0xffff; -		h.id = id; -		dns = nsip[ns]; -		UNLOCK; +		++local_id; +		local_id &= 0xffff; +		h.id = local_id; +		dns = nsip[local_ns];  		h.qdcount = 1;  		h.rd = 1; @@ -802,13 +804,10 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  		DPRINTF("id = %d, qr = %d\n", h.id, h.qr); -		LOCK; -		if ((h.id != id) || (!h.qr)) { -			UNLOCK; +		if ((h.id != local_id) || (!h.qr)) {  			/* unsolicited */  			goto again;  		} -		UNLOCK;  		DPRINTF("Got response %s\n", "(i think)!"); @@ -861,6 +860,13 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  		else  			free(packet);  		free(lookup); + +		/* Mess with globals while under lock */ +		LOCK; +		ns = local_ns; +		id = local_id; +		UNLOCK; +  		return (len);				/* success! */  	  tryall: @@ -868,12 +874,10 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  		   otherwise return with error */  		{  		    variant = -1; -                    LOCK; -                    ns = (ns + 1) % nscount; -                    if (ns == 0) +                    local_ns = (local_ns + 1) % nscount; +                    if (local_ns == 0)                        retries++; -                    UNLOCK;                      continue;  		} @@ -890,12 +894,10 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,  			variant++;  		    } else {  			/* next server, first search */ -			LOCK; -			ns = (ns + 1) % nscount; -                        if (ns == 0) +			local_ns = (local_ns + 1) % nscount; +                        if (local_ns == 0)                            retries++; -			UNLOCK;  			variant = -1;  		    }  		} @@ -909,6 +911,11 @@ fail:  	if (packet)  	    free(packet);  	h_errno = NETDB_INTERNAL; +	/* Mess with globals while under lock */ +	LOCK; +	ns = local_ns; +	id = local_id; +	UNLOCK;  	return -1;  }  #endif | 
