Eek, staticize a couple of functions that shouldn't
be external (initialize()!). Remove cancellation points from _pthread_cond_wait and _pthread_cond_timedwait (single underscore versions are libc private functions). Point the weak reference(!) for these functions to the versions with cancellation points. Approved by: re@(blanket till 5/19) Pointed out by: kan (cancellation point bug)
This commit is contained in:
parent
da1b9f9f88
commit
b26e5b44e0
@ -49,10 +49,16 @@ static inline struct pthread *cond_queue_deq(pthread_cond_t);
|
||||
static inline void cond_queue_remove(pthread_cond_t, pthread_t);
|
||||
static inline void cond_queue_enq(pthread_cond_t, pthread_t);
|
||||
|
||||
/*
|
||||
* Double underscore versions are cancellation points. Single underscore
|
||||
* versions are not and are provided for libc internal usage (which
|
||||
* shouldn't introduce cancellation points).
|
||||
*/
|
||||
__weak_reference(__pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
|
||||
__weak_reference(_pthread_cond_init, pthread_cond_init);
|
||||
__weak_reference(_pthread_cond_destroy, pthread_cond_destroy);
|
||||
__weak_reference(_pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(_pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
__weak_reference(_pthread_cond_signal, pthread_cond_signal);
|
||||
__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast);
|
||||
|
||||
@ -167,22 +173,16 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
int unlock_mutex = 1;
|
||||
int seqno;
|
||||
|
||||
_thr_enter_cancellation_point(curthread);
|
||||
|
||||
if (cond == NULL) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
if (cond == NULL)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the condition variable is statically initialized,
|
||||
* perform the dynamic initialization:
|
||||
*/
|
||||
if (*cond == NULL &&
|
||||
(rval = pthread_cond_init(cond, NULL)) != 0) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
(rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
@ -348,8 +348,6 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
curthread->continuation((void *) curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
@ -379,21 +377,16 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
|
||||
THR_ASSERT(curthread->locklevel == 0,
|
||||
"cv_timedwait: locklevel is not zero!");
|
||||
_thr_enter_cancellation_point(curthread);
|
||||
|
||||
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
|
||||
abstime->tv_nsec >= 1000000000) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
abstime->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
@ -556,8 +549,6 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
curthread->continuation((void *)curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
@ -117,6 +117,9 @@ static int inited = 0;
|
||||
static int active_kse_count = 0;
|
||||
static int active_kseg_count = 0;
|
||||
|
||||
#ifdef DEBUG_THREAD_KERN
|
||||
static void dump_queues(struct kse *curkse);
|
||||
#endif
|
||||
static void kse_check_completed(struct kse *kse);
|
||||
static void kse_check_waitq(struct kse *kse);
|
||||
static void kse_check_signals(struct kse *kse);
|
||||
@ -762,7 +765,8 @@ kse_sched_single(struct kse *curkse)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
#ifdef DEBUG_THREAD_KERN
|
||||
static void
|
||||
dump_queues(struct kse *curkse)
|
||||
{
|
||||
struct pthread *thread;
|
||||
@ -773,6 +777,7 @@ dump_queues(struct kse *curkse)
|
||||
thread, thread->state, thread->blocked);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the scheduler for a KSE which runs multiple threads.
|
||||
|
@ -40,8 +40,10 @@ __FBSDID("$FreeBSD$");
|
||||
extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask);
|
||||
|
||||
__weak_reference(_pselect, pselect);
|
||||
|
||||
int
|
||||
pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
|
@ -48,7 +48,9 @@ __FBSDID("$FreeBSD$");
|
||||
static unsigned int ldt_mask[LDT_WORDS];
|
||||
static int initialized = 0;
|
||||
|
||||
void
|
||||
static void initialize(void);
|
||||
|
||||
static void
|
||||
initialize(void)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -49,10 +49,16 @@ static inline struct pthread *cond_queue_deq(pthread_cond_t);
|
||||
static inline void cond_queue_remove(pthread_cond_t, pthread_t);
|
||||
static inline void cond_queue_enq(pthread_cond_t, pthread_t);
|
||||
|
||||
/*
|
||||
* Double underscore versions are cancellation points. Single underscore
|
||||
* versions are not and are provided for libc internal usage (which
|
||||
* shouldn't introduce cancellation points).
|
||||
*/
|
||||
__weak_reference(__pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
|
||||
__weak_reference(_pthread_cond_init, pthread_cond_init);
|
||||
__weak_reference(_pthread_cond_destroy, pthread_cond_destroy);
|
||||
__weak_reference(_pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(_pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
__weak_reference(_pthread_cond_signal, pthread_cond_signal);
|
||||
__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast);
|
||||
|
||||
@ -167,22 +173,16 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
int unlock_mutex = 1;
|
||||
int seqno;
|
||||
|
||||
_thr_enter_cancellation_point(curthread);
|
||||
|
||||
if (cond == NULL) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
if (cond == NULL)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the condition variable is statically initialized,
|
||||
* perform the dynamic initialization:
|
||||
*/
|
||||
if (*cond == NULL &&
|
||||
(rval = pthread_cond_init(cond, NULL)) != 0) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
(rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
@ -348,8 +348,6 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
curthread->continuation((void *) curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
@ -379,21 +377,16 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
|
||||
THR_ASSERT(curthread->locklevel == 0,
|
||||
"cv_timedwait: locklevel is not zero!");
|
||||
_thr_enter_cancellation_point(curthread);
|
||||
|
||||
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
|
||||
abstime->tv_nsec >= 1000000000) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
abstime->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0) {
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a loop waiting for a condition signal or broadcast
|
||||
@ -556,8 +549,6 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
curthread->continuation((void *)curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thr_leave_cancellation_point(curthread);
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
@ -117,6 +117,9 @@ static int inited = 0;
|
||||
static int active_kse_count = 0;
|
||||
static int active_kseg_count = 0;
|
||||
|
||||
#ifdef DEBUG_THREAD_KERN
|
||||
static void dump_queues(struct kse *curkse);
|
||||
#endif
|
||||
static void kse_check_completed(struct kse *kse);
|
||||
static void kse_check_waitq(struct kse *kse);
|
||||
static void kse_check_signals(struct kse *kse);
|
||||
@ -762,7 +765,8 @@ kse_sched_single(struct kse *curkse)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
#ifdef DEBUG_THREAD_KERN
|
||||
static void
|
||||
dump_queues(struct kse *curkse)
|
||||
{
|
||||
struct pthread *thread;
|
||||
@ -773,6 +777,7 @@ dump_queues(struct kse *curkse)
|
||||
thread, thread->state, thread->blocked);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the scheduler for a KSE which runs multiple threads.
|
||||
|
@ -40,8 +40,10 @@ __FBSDID("$FreeBSD$");
|
||||
extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask);
|
||||
|
||||
__weak_reference(_pselect, pselect);
|
||||
|
||||
int
|
||||
pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
|
Loading…
Reference in New Issue
Block a user