Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use ReentrantLock in LockUtil (Switch) #1092

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions actor/src/main/scala/org/apache/pekko/util/LockUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ final class ReentrantGuard extends ReentrantLock {
*/
class Switch(startAsOn: Boolean = false) {
private val switch = new AtomicBoolean(startAsOn) // FIXME switch to AQS
private val lock = new ReentrantGuard()

protected def transcend(from: Boolean, action: => Unit): Boolean = synchronized {
protected def transcend(from: Boolean, action: => Unit): Boolean = lock.withGuard {
if (switch.compareAndSet(from, !from)) {
try action
catch {
Expand Down Expand Up @@ -60,12 +61,12 @@ class Switch(startAsOn: Boolean = false) {
/**
* Switches the switch off (if on), uses locking
*/
def switchOff: Boolean = synchronized { switch.compareAndSet(true, false) }
def switchOff: Boolean = lock.withGuard { switch.compareAndSet(true, false) }

/**
* Switches the switch on (if off), uses locking
*/
def switchOn: Boolean = synchronized { switch.compareAndSet(false, true) }
def switchOn: Boolean = lock.withGuard { switch.compareAndSet(false, true) }

/**
* Executes the provided action and returns its value if the switch is IMMEDIATELY on (i.e. no lock involved)
Expand Down Expand Up @@ -101,19 +102,19 @@ class Switch(startAsOn: Boolean = false) {
* Executes the provided action and returns its value if the switch is on, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOnYield[T](action: => T): Option[T] = synchronized { if (switch.get) Some(action) else None }
def whileOnYield[T](action: => T): Option[T] = lock.withGuard { if (switch.get) Some(action) else None }

/**
* Executes the provided action and returns its value if the switch is off, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOffYield[T](action: => T): Option[T] = synchronized { if (!switch.get) Some(action) else None }
def whileOffYield[T](action: => T): Option[T] = lock.withGuard { if (!switch.get) Some(action) else None }

/**
* Executes the provided action and returns if the action was executed or not, if the switch is on, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOn(action: => Unit): Boolean = synchronized {
def whileOn(action: => Unit): Boolean = lock.withGuard {
if (switch.get) {
action
true
Expand All @@ -124,7 +125,7 @@ class Switch(startAsOn: Boolean = false) {
* Executes the provided action and returns if the action was executed or not, if the switch is off, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOff(action: => Unit): Boolean = synchronized {
def whileOff(action: => Unit): Boolean = lock.withGuard {
if (!switch.get) {
action
true
Expand All @@ -135,12 +136,12 @@ class Switch(startAsOn: Boolean = false) {
* Executes the provided callbacks depending on if the switch is either on or off waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def fold[T](on: => T)(off: => T): T = synchronized { if (switch.get) on else off }
def fold[T](on: => T)(off: => T): T = lock.withGuard { if (switch.get) on else off }

/**
* Executes the given code while holding this switch’s lock, i.e. protected from concurrent modification of the switch status.
*/
def locked[T](code: => T): T = synchronized { code }
def locked[T](code: => T): T = lock.withGuard { code }

/**
* Returns whether the switch is IMMEDIATELY on (no locking)
Expand Down
Loading