2fe8fb192f
There is important information about booting non-ack images in docs/UPDATING. ack/aout-format images can't be built any more, and booting clang/ELF-format ones is a little different. Updating to the new boot monitor is recommended. Changes in this commit: . drop boot monitor -> allowing dropping ack support . facility to copy ELF boot files to /boot so that old boot monitor can still boot fairly easily, see UPDATING . no more ack-format libraries -> single-case libraries . some cleanup of OBJECT_FMT, COMPILER_TYPE, etc cases . drop several ack toolchain commands, but not all support commands (e.g. aal is gone but acksize is not yet). . a few libc files moved to netbsd libc dir . new /bin/date as minix date used code in libc/ . test compile fix . harmonize includes . /usr/lib is no longer special: without ack, /usr/lib plays no kind of special bootstrapping role any more and bootstrapping is done exclusively through packages, so releases depend even less on the state of the machine making them now. . rename nbsd_lib* to lib* . reduce mtree
130 lines
2.5 KiB
C
130 lines
2.5 KiB
C
/* $NetBSD: mtctxres.c,v 1.4 2007/03/30 20:40:52 ghen Exp $ */
|
|
|
|
#include <port_before.h>
|
|
#ifdef DO_PTHREADS
|
|
#include <pthread.h>
|
|
#endif
|
|
#include <errno.h>
|
|
#include <netdb.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <resolv_mt.h>
|
|
#include <port_after.h>
|
|
|
|
#ifdef DO_PTHREADS
|
|
static pthread_key_t key;
|
|
static int mt_key_initialized = 0;
|
|
|
|
static int __res_init_ctx(void);
|
|
static void __res_destroy_ctx(void *);
|
|
|
|
#if defined(sun) && !defined(__GNUC__)
|
|
#pragma init (_mtctxres_init)
|
|
#endif
|
|
#endif
|
|
|
|
static mtctxres_t sharedctx;
|
|
|
|
#ifdef DO_PTHREADS
|
|
/*
|
|
* Initialize the TSD key. By doing this at library load time, we're
|
|
* implicitly running without interference from other threads, so there's
|
|
* no need for locking.
|
|
*/
|
|
static void
|
|
_mtctxres_init(void) {
|
|
int pthread_keycreate_ret;
|
|
|
|
pthread_keycreate_ret = pthread_key_create(&key, __res_destroy_ctx);
|
|
if (pthread_keycreate_ret == 0)
|
|
mt_key_initialized = 1;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* To support binaries that used the private MT-safe interface in
|
|
* Solaris 8, we still need to provide the __res_enable_mt()
|
|
* and __res_disable_mt() entry points. They're do-nothing routines.
|
|
*/
|
|
int
|
|
__res_enable_mt(void) {
|
|
return (-1);
|
|
}
|
|
|
|
int
|
|
__res_disable_mt(void) {
|
|
return (0);
|
|
}
|
|
|
|
#ifdef DO_PTHREADS
|
|
static int
|
|
__res_init_ctx(void) {
|
|
|
|
mtctxres_t *mt;
|
|
int ret;
|
|
|
|
|
|
if (pthread_getspecific(key) != 0) {
|
|
/* Already exists */
|
|
return (0);
|
|
}
|
|
|
|
if ((mt = malloc(sizeof (mtctxres_t))) == 0) {
|
|
errno = ENOMEM;
|
|
return (-1);
|
|
}
|
|
|
|
memset(mt, 0, sizeof (mtctxres_t));
|
|
|
|
if ((ret = pthread_setspecific(key, mt)) != 0) {
|
|
free(mt);
|
|
errno = ret;
|
|
return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void
|
|
__res_destroy_ctx(void *value) {
|
|
|
|
mtctxres_t *mt = (mtctxres_t *)value;
|
|
|
|
if (mt != 0)
|
|
free(mt);
|
|
}
|
|
#endif
|
|
|
|
mtctxres_t *
|
|
___mtctxres(void) {
|
|
#ifdef DO_PTHREADS
|
|
mtctxres_t *mt;
|
|
|
|
/*
|
|
* This if clause should only be executed if we are linking
|
|
* statically. When linked dynamically _mtctxres_init() should
|
|
* be called at binding time due the #pragma above.
|
|
*/
|
|
if (!mt_key_initialized) {
|
|
static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
|
|
if (pthread_mutex_lock(&keylock) == 0) {
|
|
_mtctxres_init();
|
|
(void) pthread_mutex_unlock(&keylock);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If we have already been called in this thread return the existing
|
|
* context. Otherwise recreat a new context and return it. If
|
|
* that fails return a global context.
|
|
*/
|
|
if (mt_key_initialized) {
|
|
if (((mt = pthread_getspecific(key)) != 0) ||
|
|
(__res_init_ctx() == 0 &&
|
|
(mt = pthread_getspecific(key)) != 0)) {
|
|
return (mt);
|
|
}
|
|
}
|
|
#endif
|
|
return (&sharedctx);
|
|
}
|