示例#1
0
/*
 * Call all handlers registered with __cxa_atexit for the shared
 * object owning 'dso'.  Note: if 'dso' is NULL, then all remaining
 * handlers are called.
 */
void
__cxa_finalize(void *dso)
{
	struct dl_phdr_info phdr_info;
	struct atexit *p;
	struct atexit_fn fn;
	int n, has_phdr;

	if (dso != NULL) {
		has_phdr = _rtld_addr_phdr(dso, &phdr_info);
	} else {
		has_phdr = 0;
		global_exit = 1;
	}

	_MUTEX_LOCK(&atexit_mutex);
	for (p = __atexit; p; p = p->next) {
		for (n = p->ind; --n >= 0;) {
			if (p->fns[n].fn_type == ATEXIT_FN_EMPTY)
				continue; /* already been called */
			fn = p->fns[n];
			if (dso != NULL && dso != fn.fn_dso) {
				/* wrong DSO ? */
				if (!has_phdr || global_exit ||
				    !__elf_phdr_match_addr(&phdr_info,
				    fn.fn_ptr.cxa_func))
					continue;
			}
			/*
			  Mark entry to indicate that this particular handler
			  has already been called.
			*/
			p->fns[n].fn_type = ATEXIT_FN_EMPTY;
		        _MUTEX_UNLOCK(&atexit_mutex);
		
			/* Call the function of correct type. */
			if (fn.fn_type == ATEXIT_FN_CXA)
				fn.fn_ptr.cxa_func(fn.fn_arg);
			else if (fn.fn_type == ATEXIT_FN_STD)
				fn.fn_ptr.std_func();
			_MUTEX_LOCK(&atexit_mutex);
		}
	}
	_MUTEX_UNLOCK(&atexit_mutex);
	if (dso == NULL)
		_MUTEX_DESTROY(&atexit_mutex);

	if (has_phdr && !global_exit && &__pthread_cxa_finalize != NULL)
		__pthread_cxa_finalize(&phdr_info);
}
示例#2
0
void
_thr_tsd_unload(struct dl_phdr_info *phdr_info)
{
	struct pthread *curthread = _get_curthread();
	void (*destructor)(void *);
	int key;

	THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
	for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
		if (_thread_keytable[key].allocated) {
			destructor = _thread_keytable[key].destructor;
			if (destructor != NULL) {
				if (__elf_phdr_match_addr(phdr_info, destructor))
					_thread_keytable[key].destructor = NULL;
			}
		}
	}
	THR_LOCK_RELEASE(curthread, &_keytable_lock);
}