@@ -1840,6 +1840,15 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
18401840 WOLFSENTRY_ERROR_RETURN (BUSY );
18411841 }
18421842
1843+ if ((lock -> read_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1844+ (thread -> shared_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
1845+ {
1846+ if (sem_post (& lock -> sem ) < 0 )
1847+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
1848+ else
1849+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
1850+ }
1851+
18431852 ++ lock -> read_waiter_count ;
18441853
18451854 if (sem_post (& lock -> sem ) < 0 )
@@ -1899,7 +1908,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
18991908 thread -> tracked_shared_lock = lock ;
19001909 thread -> recursion_of_tracked_lock = 1 ;
19011910 }
1902- else if (thread -> tracked_shared_lock == lock )
1911+ else if (thread -> tracked_shared_lock == lock ) /* can't happen */
19031912 ++ thread -> recursion_of_tracked_lock ;
19041913
19051914 if ((flags & (WOLFSENTRY_LOCK_FLAG_GET_RESERVATION_TOO | WOLFSENTRY_LOCK_FLAG_TRY_RESERVATION_TOO )) &&
@@ -1961,6 +1970,18 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared_abstimed(struct wolfs
19611970 store_reservation = 1 ;
19621971 }
19631972
1973+ if ((lock -> read_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1974+ (thread -> shared_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
1975+ ((thread -> tracked_shared_lock == lock ) && (thread -> recursion_of_tracked_lock == WOLFSENTRY_RWLOCK_MAX_COUNT )) ||
1976+ (lock -> holder_count .read >= WOLFSENTRY_RWLOCK_MAX_COUNT - store_reservation ) ||
1977+ (store_reservation && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
1978+ {
1979+ if (sem_post (& lock -> sem ) < 0 )
1980+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
1981+ else
1982+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
1983+ }
1984+
19641985 if (lock -> state == WOLFSENTRY_LOCK_UNLOCKED )
19651986 WOLFSENTRY_ATOMIC_STORE (lock -> state , WOLFSENTRY_LOCK_SHARED );
19661987
@@ -2031,6 +2052,11 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
20312052 case WOLFSENTRY_LOCK_EXCLUSIVE :
20322053 if (WOLFSENTRY_ATOMIC_LOAD (lock -> write_lock_holder ) == WOLFSENTRY_THREAD_GET_ID ) {
20332054 if (! (flags & WOLFSENTRY_LOCK_FLAG_NONRECURSIVE_MUTEX )) {
2055+ if ((lock -> holder_count .write == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2056+ (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
2057+ {
2058+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2059+ }
20342060 /* recursively locking while holding write is effectively uncontended. */
20352061 ++ lock -> holder_count .write ;
20362062 if (thread )
@@ -2047,18 +2073,22 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
20472073 if (flags & WOLFSENTRY_LOCK_FLAG_NONRECURSIVE_MUTEX )
20482074 WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
20492075 else {
2076+ if (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2077+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
20502078 ret = wolfsentry_lock_shared2mutex_redeem_abstimed (lock , thread , abs_timeout , flags );
20512079 WOLFSENTRY_RERETURN_IF_ERROR (ret );
2052- ++ lock -> holder_count .write ;
2080+ ++ lock -> holder_count .write ; /* caller now holds the lock at least 2 deep. */
20532081 if (thread )
20542082 ++ thread -> mutex_and_reservation_count ;
20552083 WOLFSENTRY_RETURN_OK ;
20562084 }
20572085 }
20582086 else if (thread && (thread -> tracked_shared_lock == lock )) {
2087+ if (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2088+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
20592089 ret = wolfsentry_lock_shared2mutex_abstimed (lock , thread , abs_timeout , flags );
20602090 WOLFSENTRY_RERETURN_IF_ERROR (ret );
2061- ++ lock -> holder_count .write ;
2091+ ++ lock -> holder_count .write ; /* caller now holds the lock at least 2 deep. */
20622092 if (thread )
20632093 ++ thread -> mutex_and_reservation_count ;
20642094 WOLFSENTRY_RETURN_OK ;
@@ -2125,6 +2155,14 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex_abstimed(struct wolfse
21252155 WOLFSENTRY_ERROR_RETURN (BUSY );
21262156 }
21272157
2158+ if ((lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2159+ (thread && (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )))
2160+ {
2161+ if (sem_post (& lock -> sem ) < 0 )
2162+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2163+ else
2164+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2165+ }
21282166 ++ lock -> write_waiter_count ;
21292167
21302168 if (sem_post (& lock -> sem ) < 0 )
@@ -2272,15 +2310,29 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_mutex2shared(struct wolfsent
22722310 WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
22732311 }
22742312
2313+ if (thread -> shared_count >= WOLFSENTRY_RWLOCK_MAX_COUNT - lock -> holder_count .write ) {
2314+ if (sem_post (& lock -> sem ) < 0 )
2315+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2316+ else
2317+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2318+ }
2319+
22752320 if (flags & (WOLFSENTRY_LOCK_FLAG_GET_RESERVATION_TOO | WOLFSENTRY_LOCK_FLAG_TRY_RESERVATION_TOO )) {
2276- /* can't happen, but be sure. */
2277- if (lock -> read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID ) {
2321+ if (lock -> read2write_reservation_holder != WOLFSENTRY_THREAD_NO_ID ) /* can't happen, but be sure. */ {
22782322 if (sem_post (& lock -> sem ) < 0 )
22792323 WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
22802324 WOLFSENTRY_ERROR_RETURN (INTERNAL_CHECK_FATAL );
22812325 }
2282- WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , lock -> write_lock_holder );
2326+ if ((thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT ) ||
2327+ (lock -> holder_count .write == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2328+ {
2329+ if (sem_post (& lock -> sem ) < 0 )
2330+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2331+ else
2332+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2333+ }
22832334 ++ thread -> mutex_and_reservation_count ;
2335+ WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , lock -> write_lock_holder );
22842336 lock -> read2write_waiter_read_count = lock -> holder_count .write ;
22852337 /* note, not incrementing write_waiter_count, to allow shared lockers to get locks until the redemption phase. */
22862338 }
@@ -2344,6 +2396,9 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_reserve(struct
23442396 WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
23452397 }
23462398
2399+ if (thread -> mutex_and_reservation_count == WOLFSENTRY_RWLOCK_MAX_COUNT )
2400+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2401+
23472402 for (;;) {
23482403 int ret = sem_wait (& lock -> sem );
23492404 if (ret == 0 )
@@ -2369,6 +2424,13 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_reserve(struct
23692424 WOLFSENTRY_ERROR_RETURN (BUSY );
23702425 }
23712426
2427+ if (lock -> holder_count .read == WOLFSENTRY_RWLOCK_MAX_COUNT ) {
2428+ if (sem_post (& lock -> sem ) < 0 )
2429+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2430+ else
2431+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2432+ }
2433+
23722434 WOLFSENTRY_ATOMIC_STORE (lock -> read2write_reservation_holder , WOLFSENTRY_THREAD_GET_ID );
23732435 ++ thread -> mutex_and_reservation_count ;
23742436 /* note, not incrementing write_waiter_count, to allow shared lockers to get locks until the redemption phase. */
@@ -2457,6 +2519,15 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_redeem_abstimed
24572519 WOLFSENTRY_ERROR_RETURN (INCOMPATIBLE_STATE );
24582520 }
24592521
2522+ if ((thread -> mutex_and_reservation_count >= WOLFSENTRY_RWLOCK_MAX_COUNT - lock -> read2write_waiter_read_count ) ||
2523+ (lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2524+ {
2525+ if (sem_post (& lock -> sem ) < 0 )
2526+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2527+ else
2528+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2529+ }
2530+
24602531 if (lock -> holder_count .read == lock -> read2write_waiter_read_count + 1 ) {
24612532 -- lock -> holder_count .read ; /* remove extra count associated with the reservation. */
24622533 lock -> promoted_at_count = lock -> holder_count .read ;
@@ -2713,6 +2784,17 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_abstimed(struct
27132784 WOLFSENTRY_ERROR_RETURN (BUSY );
27142785 }
27152786
2787+ if ((thread -> mutex_and_reservation_count
2788+ >=
2789+ ((thread -> tracked_shared_lock == lock ) ? WOLFSENTRY_RWLOCK_MAX_COUNT : (WOLFSENTRY_RWLOCK_MAX_COUNT - thread -> recursion_of_tracked_lock ))) ||
2790+ (lock -> write_waiter_count == WOLFSENTRY_RWLOCK_MAX_COUNT ))
2791+ {
2792+ if (sem_post (& lock -> sem ) < 0 )
2793+ WOLFSENTRY_ERROR_RETURN (SYS_OP_FATAL );
2794+ else
2795+ WOLFSENTRY_ERROR_RETURN (OVERFLOW_AVERTED );
2796+ }
2797+
27162798 if ((lock -> holder_count .read == 1 )
27172799 || ((thread -> tracked_shared_lock == lock )
27182800 && (lock -> holder_count .read == thread -> recursion_of_tracked_lock )))
0 commit comments