1 /* $NetBSD: res_state.c,v 1.5 2007/11/13 15:57:14 ad Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 __RCSID("$NetBSD: res_state.c,v 1.5 2007/11/13 15:57:14 ad Exp $");
37 #include <sys/types.h>
38 #include <sys/queue.h>
39 #include <arpa/inet.h>
40 #include <arpa/nameser.h>
47 #include "pthread_int.h"
49 static SLIST_HEAD(, _res_st
) res_list
= LIST_HEAD_INITIALIZER(&res_list
);
52 /* __res_put_state() assumes st_res is the first member. */
53 struct __res_state st_res
;
55 SLIST_ENTRY(_res_st
) st_list
;
58 static pthread_mutex_t res_mtx
= PTHREAD_MUTEX_INITIALIZER
;
60 res_state
__res_state(void);
61 res_state
__res_get_state(void);
62 void __res_put_state(res_state
);
64 #ifdef RES_STATE_DEBUG
66 res_state_debug(const char *msg
, void *p
)
69 pthread_t self
= pthread__self();
70 int len
= snprintf(buf
, sizeof(buf
), "%p: %s %p\n", self
, msg
, p
);
72 (void)write(STDOUT_FILENO
, buf
, (size_t)len
);
75 #define res_state_debug(a, b)
84 pthread_mutex_lock(&res_mtx
);
85 st
= SLIST_FIRST(&res_list
);
87 SLIST_REMOVE_HEAD(&res_list
, st_list
);
88 pthread_mutex_unlock(&res_mtx
);
90 res_state_debug("checkout from list", st
);
92 pthread_mutex_unlock(&res_mtx
);
93 st
= malloc(sizeof(*st
));
95 h_errno
= NETDB_INTERNAL
;
100 res_state_debug("alloc new", res
);
102 if ((res
->options
& RES_INIT
) == 0) {
103 if (res_ninit(res
) == -1) {
104 h_errno
= NETDB_INTERNAL
;
114 __res_put_state(res_state res
)
116 struct _res_st
*st
= (struct _res_st
*)(void *)res
;
118 res_state_debug("free", res
);
119 pthread_mutex_lock(&res_mtx
);
120 SLIST_INSERT_HEAD(&res_list
, st
, st_list
);
121 pthread_mutex_unlock(&res_mtx
);
125 * This is aliased via a macro to _res; don't allow multi-threaded programs
131 static const char res
[] = "_res is not supported for multi-threaded"
133 (void)write(STDERR_FILENO
, res
, sizeof(res
) - 1);