1*11038SRao.Shoaib@Sun.COM /* 2*11038SRao.Shoaib@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3*11038SRao.Shoaib@Sun.COM * Use is subject to license terms. 4*11038SRao.Shoaib@Sun.COM */ 5*11038SRao.Shoaib@Sun.COM 6*11038SRao.Shoaib@Sun.COM 7*11038SRao.Shoaib@Sun.COM #include <port_before.h> 8*11038SRao.Shoaib@Sun.COM #ifdef DO_PTHREADS 9*11038SRao.Shoaib@Sun.COM #include <pthread.h> 10*11038SRao.Shoaib@Sun.COM #endif 11*11038SRao.Shoaib@Sun.COM #include <errno.h> 12*11038SRao.Shoaib@Sun.COM #include <netdb.h> 13*11038SRao.Shoaib@Sun.COM #include <stdlib.h> 14*11038SRao.Shoaib@Sun.COM #include <string.h> 15*11038SRao.Shoaib@Sun.COM #include <resolv_mt.h> 16*11038SRao.Shoaib@Sun.COM #include <irs.h> 17*11038SRao.Shoaib@Sun.COM #include <port_after.h> 18*11038SRao.Shoaib@Sun.COM 19*11038SRao.Shoaib@Sun.COM #ifdef DO_PTHREADS 20*11038SRao.Shoaib@Sun.COM static pthread_key_t key; 21*11038SRao.Shoaib@Sun.COM static int mt_key_initialized = 0; 22*11038SRao.Shoaib@Sun.COM 23*11038SRao.Shoaib@Sun.COM static int __res_init_ctx(void); 24*11038SRao.Shoaib@Sun.COM static void __res_destroy_ctx(void *); 25*11038SRao.Shoaib@Sun.COM 26*11038SRao.Shoaib@Sun.COM #if defined(sun) && !defined(__GNUC__) 27*11038SRao.Shoaib@Sun.COM #pragma init (_mtctxres_init) 28*11038SRao.Shoaib@Sun.COM #endif 29*11038SRao.Shoaib@Sun.COM #endif 30*11038SRao.Shoaib@Sun.COM 31*11038SRao.Shoaib@Sun.COM static mtctxres_t sharedctx; 32*11038SRao.Shoaib@Sun.COM 33*11038SRao.Shoaib@Sun.COM #ifdef DO_PTHREADS 34*11038SRao.Shoaib@Sun.COM /* 35*11038SRao.Shoaib@Sun.COM * Initialize the TSD key. By doing this at library load time, we're 36*11038SRao.Shoaib@Sun.COM * implicitly running without interference from other threads, so there's 37*11038SRao.Shoaib@Sun.COM * no need for locking. 38*11038SRao.Shoaib@Sun.COM */ 39*11038SRao.Shoaib@Sun.COM static void _mtctxres_init(void)40*11038SRao.Shoaib@Sun.COM_mtctxres_init(void) { 41*11038SRao.Shoaib@Sun.COM int pthread_keycreate_ret; 42*11038SRao.Shoaib@Sun.COM 43*11038SRao.Shoaib@Sun.COM pthread_keycreate_ret = pthread_key_create(&key, __res_destroy_ctx); 44*11038SRao.Shoaib@Sun.COM if (pthread_keycreate_ret == 0) 45*11038SRao.Shoaib@Sun.COM mt_key_initialized = 1; 46*11038SRao.Shoaib@Sun.COM } 47*11038SRao.Shoaib@Sun.COM #endif 48*11038SRao.Shoaib@Sun.COM 49*11038SRao.Shoaib@Sun.COM /* 50*11038SRao.Shoaib@Sun.COM * To support binaries that used the private MT-safe interface in 51*11038SRao.Shoaib@Sun.COM * Solaris 8, we still need to provide the __res_enable_mt() 52*11038SRao.Shoaib@Sun.COM * and __res_disable_mt() entry points. They're do-nothing routines. 53*11038SRao.Shoaib@Sun.COM */ 54*11038SRao.Shoaib@Sun.COM int __res_enable_mt(void)55*11038SRao.Shoaib@Sun.COM__res_enable_mt(void) { 56*11038SRao.Shoaib@Sun.COM return (-1); 57*11038SRao.Shoaib@Sun.COM } 58*11038SRao.Shoaib@Sun.COM 59*11038SRao.Shoaib@Sun.COM int __res_disable_mt(void)60*11038SRao.Shoaib@Sun.COM__res_disable_mt(void) { 61*11038SRao.Shoaib@Sun.COM return (0); 62*11038SRao.Shoaib@Sun.COM } 63*11038SRao.Shoaib@Sun.COM 64*11038SRao.Shoaib@Sun.COM #ifdef DO_PTHREADS 65*11038SRao.Shoaib@Sun.COM static int __res_init_ctx(void)66*11038SRao.Shoaib@Sun.COM__res_init_ctx(void) { 67*11038SRao.Shoaib@Sun.COM 68*11038SRao.Shoaib@Sun.COM mtctxres_t *mt; 69*11038SRao.Shoaib@Sun.COM int ret; 70*11038SRao.Shoaib@Sun.COM 71*11038SRao.Shoaib@Sun.COM 72*11038SRao.Shoaib@Sun.COM if (pthread_getspecific(key) != 0) { 73*11038SRao.Shoaib@Sun.COM /* Already exists */ 74*11038SRao.Shoaib@Sun.COM return (0); 75*11038SRao.Shoaib@Sun.COM } 76*11038SRao.Shoaib@Sun.COM 77*11038SRao.Shoaib@Sun.COM if ((mt = malloc(sizeof (mtctxres_t))) == 0) { 78*11038SRao.Shoaib@Sun.COM errno = ENOMEM; 79*11038SRao.Shoaib@Sun.COM return (-1); 80*11038SRao.Shoaib@Sun.COM } 81*11038SRao.Shoaib@Sun.COM 82*11038SRao.Shoaib@Sun.COM memset(mt, 0, sizeof (mtctxres_t)); 83*11038SRao.Shoaib@Sun.COM 84*11038SRao.Shoaib@Sun.COM if ((ret = pthread_setspecific(key, mt)) != 0) { 85*11038SRao.Shoaib@Sun.COM free(mt); 86*11038SRao.Shoaib@Sun.COM errno = ret; 87*11038SRao.Shoaib@Sun.COM return (-1); 88*11038SRao.Shoaib@Sun.COM } 89*11038SRao.Shoaib@Sun.COM 90*11038SRao.Shoaib@Sun.COM return (0); 91*11038SRao.Shoaib@Sun.COM } 92*11038SRao.Shoaib@Sun.COM 93*11038SRao.Shoaib@Sun.COM static void __res_destroy_ctx(void * value)94*11038SRao.Shoaib@Sun.COM__res_destroy_ctx(void *value) { 95*11038SRao.Shoaib@Sun.COM 96*11038SRao.Shoaib@Sun.COM mtctxres_t *mt = (mtctxres_t *)value; 97*11038SRao.Shoaib@Sun.COM 98*11038SRao.Shoaib@Sun.COM if (mt != 0) 99*11038SRao.Shoaib@Sun.COM free(mt); 100*11038SRao.Shoaib@Sun.COM } 101*11038SRao.Shoaib@Sun.COM #endif 102*11038SRao.Shoaib@Sun.COM 103*11038SRao.Shoaib@Sun.COM mtctxres_t * ___mtctxres(void)104*11038SRao.Shoaib@Sun.COM___mtctxres(void) { 105*11038SRao.Shoaib@Sun.COM #ifdef DO_PTHREADS 106*11038SRao.Shoaib@Sun.COM mtctxres_t *mt; 107*11038SRao.Shoaib@Sun.COM 108*11038SRao.Shoaib@Sun.COM /* 109*11038SRao.Shoaib@Sun.COM * This if clause should only be executed if we are linking 110*11038SRao.Shoaib@Sun.COM * statically. When linked dynamically _mtctxres_init() should 111*11038SRao.Shoaib@Sun.COM * be called at binding time due the #pragma above. 112*11038SRao.Shoaib@Sun.COM */ 113*11038SRao.Shoaib@Sun.COM if (!mt_key_initialized) { 114*11038SRao.Shoaib@Sun.COM static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER; 115*11038SRao.Shoaib@Sun.COM if (pthread_mutex_lock(&keylock) == 0) { 116*11038SRao.Shoaib@Sun.COM _mtctxres_init(); 117*11038SRao.Shoaib@Sun.COM (void) pthread_mutex_unlock(&keylock); 118*11038SRao.Shoaib@Sun.COM } 119*11038SRao.Shoaib@Sun.COM } 120*11038SRao.Shoaib@Sun.COM 121*11038SRao.Shoaib@Sun.COM /* 122*11038SRao.Shoaib@Sun.COM * If we have already been called in this thread return the existing 123*11038SRao.Shoaib@Sun.COM * context. Otherwise recreat a new context and return it. If 124*11038SRao.Shoaib@Sun.COM * that fails return a global context. 125*11038SRao.Shoaib@Sun.COM */ 126*11038SRao.Shoaib@Sun.COM if (mt_key_initialized) { 127*11038SRao.Shoaib@Sun.COM if (((mt = pthread_getspecific(key)) != 0) || 128*11038SRao.Shoaib@Sun.COM (__res_init_ctx() == 0 && 129*11038SRao.Shoaib@Sun.COM (mt = pthread_getspecific(key)) != 0)) { 130*11038SRao.Shoaib@Sun.COM return (mt); 131*11038SRao.Shoaib@Sun.COM } 132*11038SRao.Shoaib@Sun.COM } 133*11038SRao.Shoaib@Sun.COM #endif 134*11038SRao.Shoaib@Sun.COM return (&sharedctx); 135*11038SRao.Shoaib@Sun.COM } 136