144436c4dSjoerg /*-
244436c4dSjoerg  * Copyright (c) 2017 The NetBSD Foundation, Inc.
344436c4dSjoerg  * All rights reserved.
444436c4dSjoerg  *
544436c4dSjoerg  * This code is derived from software contributed to The NetBSD Foundation
644436c4dSjoerg  * by Joerg Sonnenberger.
744436c4dSjoerg  *
844436c4dSjoerg  * Redistribution and use in source and binary forms, with or without
944436c4dSjoerg  * modification, are permitted provided that the following conditions
1044436c4dSjoerg  * are met:
1144436c4dSjoerg  * 1. Redistributions of source code must retain the above copyright
1244436c4dSjoerg  *    notice, this list of conditions and the following disclaimer.
1344436c4dSjoerg  * 2. Redistributions in binary form must reproduce the above copyright
1444436c4dSjoerg  *    notice, this list of conditions and the following disclaimer in the
1544436c4dSjoerg  *    documentation and/or other materials provided with the distribution.
1644436c4dSjoerg  *
1744436c4dSjoerg  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1844436c4dSjoerg  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1944436c4dSjoerg  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2044436c4dSjoerg  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2144436c4dSjoerg  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2244436c4dSjoerg  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2344436c4dSjoerg  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2444436c4dSjoerg  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2544436c4dSjoerg  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2644436c4dSjoerg  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2744436c4dSjoerg  * POSSIBILITY OF SUCH DAMAGE.
2844436c4dSjoerg  */
2944436c4dSjoerg 
3044436c4dSjoerg #include <dlfcn.h>
3144436c4dSjoerg #include <err.h>
3244436c4dSjoerg #include <pthread.h>
3344436c4dSjoerg #include <stdio.h>
3444436c4dSjoerg 
3544436c4dSjoerg static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
3644436c4dSjoerg static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
3744436c4dSjoerg static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
3844436c4dSjoerg 
3944436c4dSjoerg static void *
thread_helper(void * arg)4044436c4dSjoerg thread_helper(void *arg)
4144436c4dSjoerg {
4244436c4dSjoerg 	void (*testfunc)(void) = arg;
4344436c4dSjoerg 	testfunc();
4444436c4dSjoerg 
4544436c4dSjoerg 	pthread_mutex_lock(&mutex);
4644436c4dSjoerg 	pthread_cond_broadcast(&cond1);
4744436c4dSjoerg 	pthread_mutex_unlock(&mutex);
4844436c4dSjoerg 
4944436c4dSjoerg 	pthread_mutex_lock(&mutex);
5044436c4dSjoerg 	pthread_cond_wait(&cond2, &mutex);
5144436c4dSjoerg 	pthread_mutex_unlock(&mutex);
5244436c4dSjoerg 
5344436c4dSjoerg 	return NULL;
5444436c4dSjoerg }
5544436c4dSjoerg 
5644436c4dSjoerg int
main(void)5744436c4dSjoerg main(void)
5844436c4dSjoerg {
5944436c4dSjoerg 	void *dso;
6044436c4dSjoerg 	void (*testfunc)(void);
6144436c4dSjoerg 	pthread_t thread;
6244436c4dSjoerg 
6344436c4dSjoerg 	dso = dlopen("libh_helper_dso3.so", RTLD_LAZY);
6444436c4dSjoerg 	if (dso == NULL)
6544436c4dSjoerg 		errx(1, "%s", dlerror());
6644436c4dSjoerg 	testfunc = dlsym(dso, "testfunc");
6744436c4dSjoerg 	if (testfunc == NULL)
6844436c4dSjoerg 		errx(1, "%s", dlerror());
6944436c4dSjoerg 
7044436c4dSjoerg 	pthread_mutex_lock(&mutex);
7144436c4dSjoerg 
7244436c4dSjoerg 	if (pthread_create(&thread, NULL, thread_helper, testfunc))
7344436c4dSjoerg 		err(1, "pthread_create");
7444436c4dSjoerg 
7544436c4dSjoerg 	pthread_cond_wait(&cond1, &mutex);
7644436c4dSjoerg 	pthread_mutex_unlock(&mutex);
7744436c4dSjoerg 
7844436c4dSjoerg 	printf("before dlclose\n");
7944436c4dSjoerg 	dlclose(dso);
8044436c4dSjoerg 	printf("after dlclose\n");
8144436c4dSjoerg 	dso = dlopen("libh_helper_dso3.so", RTLD_LAZY);
8244436c4dSjoerg 	if (dso == NULL)
8344436c4dSjoerg 		errx(1, "%s", dlerror());
8444436c4dSjoerg 	dlclose(dso);
85*84f398daSjoerg 
86*84f398daSjoerg 	pthread_mutex_lock(&mutex);
87*84f398daSjoerg 	pthread_cond_signal(&cond2);
88*84f398daSjoerg 	pthread_mutex_unlock(&mutex);
89*84f398daSjoerg 
9044436c4dSjoerg 	if (pthread_join(thread, NULL))
9144436c4dSjoerg 		err(1, "pthread_join");
9244436c4dSjoerg 	return 0;
9344436c4dSjoerg }
94