Page MenuHomeFreeBSD

D60958.1793454561.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D60958.1793454561.diff

diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c
--- a/lib/libthr/thread/thr_rwlock.c
+++ b/lib/libthr/thread/thr_rwlock.c
@@ -166,18 +166,9 @@
}
static int
-rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
+rdlock_flags(struct pthread *curthread)
{
- struct pthread *curthread = _get_curthread();
- pthread_rwlock_t prwlock;
- int flags;
- int ret;
-
- ret = check_and_init_rwlock(rwlock, &prwlock);
- if (ret != 0)
- return (ret);
-
- if (curthread->rdlock_count) {
+ if (curthread->rdlock_count != 0) {
/*
* To avoid having to track all the rdlocks held by
* a thread or all of the threads that hold a rdlock,
@@ -190,10 +181,31 @@
* when it already has one or more rdlocks avoids the
* deadlock. I hope the reader can follow that logic ;-)
*/
- flags = URWLOCK_PREFER_READER;
- } else {
- flags = 0;
+ return (URWLOCK_PREFER_READER);
}
+ return (0);
+}
+
+static bool
+abstime_invalid(const struct timespec *abstime)
+{
+ return (abstime != NULL &&
+ (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000));
+}
+
+static int
+rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
+{
+ struct pthread *curthread = _get_curthread();
+ pthread_rwlock_t prwlock;
+ int flags;
+ int ret;
+
+ ret = check_and_init_rwlock(rwlock, &prwlock);
+ if (ret != 0)
+ return (ret);
+
+ flags = rdlock_flags(curthread);
/*
* POSIX said the validity of the abstimeout parameter need
@@ -205,8 +217,7 @@
return (ret);
}
- if (__predict_false(abstime &&
- (abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0)))
+ if (__predict_false(abstime_invalid(abstime)))
return (EINVAL);
for (;;) {
@@ -246,7 +257,6 @@
{
struct pthread *curthread;
pthread_rwlock_t prwlock;
- int flags;
int ret;
_thr_check_init();
@@ -255,25 +265,7 @@
return (ret);
curthread = _get_curthread();
- if (curthread->rdlock_count) {
- /*
- * To avoid having to track all the rdlocks held by
- * a thread or all of the threads that hold a rdlock,
- * we keep a simple count of all the rdlocks held by
- * a thread. If a thread holds any rdlocks it is
- * possible that it is attempting to take a recursive
- * rdlock. If there are blocked writers and precedence
- * is given to them, then that would result in the thread
- * deadlocking. So allowing a thread to take the rdlock
- * when it already has one or more rdlocks avoids the
- * deadlock. I hope the reader can follow that logic ;-)
- */
- flags = URWLOCK_PREFER_READER;
- } else {
- flags = 0;
- }
-
- ret = _thr_rwlock_tryrdlock(&prwlock->lock, flags);
+ ret = _thr_rwlock_tryrdlock(&prwlock->lock, rdlock_flags(curthread));
if (ret == 0)
curthread->rdlock_count++;
return (ret);
@@ -319,8 +311,7 @@
return (ret);
}
- if (__predict_false(abstime &&
- (abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0)))
+ if (__predict_false(abstime_invalid(abstime)))
return (EINVAL);
for (;;) {

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 31, 1:49 PM (7 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41221352
Default Alt Text
D60958.1793454561.diff (2 KB)

Event Timeline