svn commit: r345501 - in stable/12: contrib/netbsd-tests/lib/libpthread lib/libthr/thread
Mark Johnston
markj at FreeBSD.org
Mon Mar 25 14:05:37 UTC 2019
Author: markj
Date: Mon Mar 25 14:05:35 2019
New Revision: 345501
URL: https://svnweb.freebsd.org/changeset/base/345501
Log:
MFC r344935:
Have pthread_cond_destroy() return EBUSY if the condvar has waiters.
PR: 234805
Modified:
stable/12/contrib/netbsd-tests/lib/libpthread/t_cond.c
stable/12/lib/libthr/thread/thr_cond.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/contrib/netbsd-tests/lib/libpthread/t_cond.c
==============================================================================
--- stable/12/contrib/netbsd-tests/lib/libpthread/t_cond.c Mon Mar 25 14:04:23 2019 (r345500)
+++ stable/12/contrib/netbsd-tests/lib/libpthread/t_cond.c Mon Mar 25 14:05:35 2019 (r345501)
@@ -493,6 +493,51 @@ ATF_TC_BODY(bogus_timedwaits, tc)
PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
}
+#ifdef __FreeBSD__
+static void *
+destroy_busy_threadfunc(void *arg)
+{
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ share = 1;
+ PTHREAD_REQUIRE(pthread_cond_broadcast(&cond));
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return NULL;
+}
+
+ATF_TC(destroy_busy);
+ATF_TC_HEAD(destroy_busy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks non-standard behaviour of "
+ "returning EBUSY when attempting to destroy an active condvar");
+}
+ATF_TC_BODY(destroy_busy, tc)
+{
+ pthread_t thread;
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, destroy_busy_threadfunc,
+ NULL));
+
+ while (share == 0) {
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ }
+
+ PTHREAD_REQUIRE_STATUS(pthread_cond_destroy(&cond), EBUSY);
+ PTHREAD_REQUIRE(pthread_cond_signal(&cond));
+ PTHREAD_REQUIRE(pthread_cond_destroy(&cond));
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+ PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex));
+}
+#endif
+
static void
unlock(void *arg)
{
@@ -547,6 +592,49 @@ ATF_TC_BODY(destroy_after_cancel, tc)
PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex));
}
+static void *
+destroy_after_signal_threadfunc(void *arg)
+{
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ share = 1;
+ PTHREAD_REQUIRE(pthread_cond_broadcast(&cond));
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return NULL;
+}
+
+ATF_TC(destroy_after_signal);
+ATF_TC_HEAD(destroy_after_signal, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks destroying a condition variable "
+ "immediately after signaling waiters");
+}
+ATF_TC_BODY(destroy_after_signal, tc)
+{
+ pthread_t thread;
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL,
+ destroy_after_signal_threadfunc, NULL));
+
+ while (share == 0) {
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ }
+
+ PTHREAD_REQUIRE(pthread_cond_signal(&cond));
+ PTHREAD_REQUIRE(pthread_cond_destroy(&cond));
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+
+ PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex));
+}
+
ATF_TC(condattr);
ATF_TC_HEAD(condattr, tc)
{
@@ -577,7 +665,11 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, cond_timedwait_race);
ATF_TP_ADD_TC(tp, broadcast);
ATF_TP_ADD_TC(tp, bogus_timedwaits);
+#ifdef __FreeBSD__
+ ATF_TP_ADD_TC(tp, destroy_busy);
+#endif
ATF_TP_ADD_TC(tp, destroy_after_cancel);
+ ATF_TP_ADD_TC(tp, destroy_after_signal);
ATF_TP_ADD_TC(tp, condattr);
return atf_no_error();
Modified: stable/12/lib/libthr/thread/thr_cond.c
==============================================================================
--- stable/12/lib/libthr/thread/thr_cond.c Mon Mar 25 14:04:23 2019 (r345500)
+++ stable/12/lib/libthr/thread/thr_cond.c Mon Mar 25 14:05:35 2019 (r345501)
@@ -166,17 +166,26 @@ _pthread_cond_destroy(pthread_cond_t *cond)
error = 0;
if (*cond == THR_PSHARED_PTR) {
cvp = __thr_pshared_offpage(cond, 0);
- if (cvp != NULL)
- __thr_pshared_destroy(cond);
- *cond = THR_COND_DESTROYED;
+ if (cvp != NULL) {
+ if (cvp->kcond.c_has_waiters)
+ error = EBUSY;
+ else
+ __thr_pshared_destroy(cond);
+ }
+ if (error == 0)
+ *cond = THR_COND_DESTROYED;
} else if ((cvp = *cond) == THR_COND_INITIALIZER) {
/* nothing */
} else if (cvp == THR_COND_DESTROYED) {
error = EINVAL;
} else {
cvp = *cond;
- *cond = THR_COND_DESTROYED;
- free(cvp);
+ if (cvp->__has_user_waiters || cvp->kcond.c_has_waiters)
+ error = EBUSY;
+ else {
+ *cond = THR_COND_DESTROYED;
+ free(cvp);
+ }
}
return (error);
}
More information about the svn-src-stable
mailing list