-plan to address both with a redesign. A proof of concept implementation was
-written and resulted in significantly simpler code.
-
-Currently ``SharedLock`` uses two separate queues for shared and exclusive
-acquires and waiters get to run in turns. This means if an exclusive acquire
-is released, the lock will allow shared waiters to run and vice versa.
-Although it's still fair in the end there is a slight bias towards shared
-waiters in the current implementation. The same implementation with two
-shared queues can not support timeouts without adding a lot of complexity.
-
-Our proposed redesign changes ``SharedLock`` to have only one single queue.
-There will be one condition (see Condition_ for a note about performance) in
-the queue per exclusive acquire and two for all shared acquires (see below for
-an explanation). The maximum queue length will always be ``2 + (number of
-exclusive acquires waiting)``. The number of queue entries for shared acquires
-can vary from 0 to 2.
-
-The two conditions for shared acquires are a bit special. They will be used
-in turn. When the lock is instantiated, no conditions are in the queue. As
-soon as the first shared acquire arrives (and there are holder(s) or waiting
-acquires; see Acquire_), the active condition is added to the queue. Until
-it becomes the topmost condition in the queue and has been notified, any
-shared acquire is added to this active condition. When the active condition
-is notified, the conditions are swapped and further shared acquires are
-added to the previously inactive condition (which has now become the active
-condition). After all waiters on the previously active (now inactive) and
-now notified condition received the notification, it is removed from the
-queue of pending acquires.
-
-This means shared acquires will skip any exclusive acquire in the queue. We
-believe it's better to improve parallelization on operations only asking for
-shared (or read-only) locks. Exclusive operations holding the same lock can
-not be parallelized.
+plan to address both with a redesign. A proof of concept implementation
+was written and resulted in significantly simpler code.
+
+Currently ``SharedLock`` uses two separate queues for shared and
+exclusive acquires and waiters get to run in turns. This means if an
+exclusive acquire is released, the lock will allow shared waiters to run
+and vice versa. Although it's still fair in the end there is a slight
+bias towards shared waiters in the current implementation. The same
+implementation with two shared queues can not support timeouts without
+adding a lot of complexity.
+
+Our proposed redesign changes ``SharedLock`` to have only one single
+queue. There will be one condition (see Condition_ for a note about
+performance) in the queue per exclusive acquire and two for all shared
+acquires (see below for an explanation). The maximum queue length will
+always be ``2 + (number of exclusive acquires waiting)``. The number of
+queue entries for shared acquires can vary from 0 to 2.
+
+The two conditions for shared acquires are a bit special. They will be
+used in turn. When the lock is instantiated, no conditions are in the
+queue. As soon as the first shared acquire arrives (and there are
+holder(s) or waiting acquires; see Acquire_), the active condition is
+added to the queue. Until it becomes the topmost condition in the queue
+and has been notified, any shared acquire is added to this active
+condition. When the active condition is notified, the conditions are
+swapped and further shared acquires are added to the previously inactive
+condition (which has now become the active condition). After all waiters
+on the previously active (now inactive) and now notified condition
+received the notification, it is removed from the queue of pending
+acquires.
+
+This means shared acquires will skip any exclusive acquire in the queue.
+We believe it's better to improve parallelization on operations only
+asking for shared (or read-only) locks. Exclusive operations holding the
+same lock can not be parallelized.