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

Fix context lock removal #10273

Merged
merged 6 commits into from
Jul 16, 2024
Merged

Fix context lock removal #10273

merged 6 commits into from
Jul 16, 2024

Conversation

hubertp
Copy link
Collaborator

@hubertp hubertp commented Jun 13, 2024

Pull Request Description

Removal of context lock assumed that one still holds a lock on it. This is no longer the case when using a withContextLock block that correctly manages the resource. This change fixes the IllegalMonitorStateException.
Closes #10254.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
  • All code follows the
    Scala,
    Java,
    TypeScript,
    and
    Rust
    style guides. In case you are using a language not listed above, follow the Rust style guide.
  • Unit tests have been written where possible.

Removal of context lock assumed that one still holds a lock on it. This
is no longer the case when using a `withContextLock` block that
correctly manages the resource. This change fixes the
`IllegalMonitorStateException`.
Closes #10354.
@hubertp hubertp added the CI: No changelog needed Do not require a changelog entry for this PR. label Jun 13, 2024
Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context lock is automatically created by withContextLock - why it is not cleaned at the end of the withContextLock method? That's the intended behavior of withXyz methods - we should delete the removeContextLock method.

@@ -248,7 +248,10 @@ class ReentrantLocking(logger: TruffleLogger) extends Locking {
contextMapLock.lock()
try {
if (contextLocks.contains(contextId)) {
contextLocks(contextId).unlock()
assertNotLocked(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the desired behavior. Why do we have removeContextLock at all? Because of this line? Then just remove it!

Copy link
Collaborator Author

@hubertp hubertp Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I suppose it was added to avoid creating new instances of ReentrantLock. Once the lock is created it is re-used. It saves roughly 10ms per command (as that particular lock is required quite often).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everywhere, where ctx.locking.withContextLock( is used, there is an instance of RuntimeContext. To

avoid creating new instances of ReentrantLock

the RuntimeContext shall obtain some object instance via ctx.locking.createContextLock and then use it via ctx.locking.withContextLock( until it is needed. At the end it should close it (removeContextLock).

Copy link
Member

@JaroslavTulach JaroslavTulach Jul 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible API could look like:

diff --git engine/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/execution/Locking.java engine/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/execution/Locking.java
index fc6e3f6389..b223ce34fb 100644
--- engine/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/execution/Locking.java
+++ engine/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/execution/Locking.java
@@ -37,21 +37,25 @@ public interface Locking {
   <T> T withPendingEditsLock(Class<?> where, Callable<T> callable);
 
   /**
-   * Executes `callable` while holding a context lock
+   * Allocates new handle for use in {@link #withContextLock} associated with given context ID.
    *
-   * @param contextId context id for which the lock is being requested
-   * @param where the class requesting the lock
-   * @param callable code to be executed while holding the lock
-   * @return the result of calling `callable` or null, if no result is expected
+   * @param contextId context ID
+   * @return an object to pass to {@link #withContextLock} and to {@link AutoCloseable#close()} when
+   *     no longer needed
    */
-  <T> T withContextLock(UUID contextId, Class<?> where, Callable<T> callable);
+  AutoCloseable createContextLock(UUID contextId);
 
   /**
-   * Removes a context lock.
+   * Executes `callable` while holding a context lock
    *
-   * @param contextId a context to remove
+   * @param contextLockHandle handle created by {@link #createContextLock(UUID)}
+   * @param where the class requesting the lock
+   * @param callable code to be executed while holding the lock
+   * @return the result of calling `callable` or null, if no result is expected
+   * @throws ClassCastException if {@code contextLockHandle} isn't coming from {@link
+   *     #createContextLock(UUID)}
    */
-  void removeContextLock(UUID contextId);
+  <T> T withContextLock(AutoCloseable contextLockHandle, Class<?> where, Callable<T> callable);
 
   /**
    * Executes `callable` while holding a file lock

More advanced tricks with generics (to hide ClassCastException from the docs) are possible, but probably unnecessary.

@JaroslavTulach JaroslavTulach self-requested a review July 6, 2024 05:45
Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully the AutoCloseable solution will be easy to implement.

@hubertp hubertp requested a review from JaroslavTulach July 15, 2024 21:23
@hubertp
Copy link
Collaborator Author

hubertp commented Jul 15, 2024

Tried to address your comment @JaroslavTulach, didn't really see the need for AutoCloseable. If still not good, please feel free to send a patch to this PR

@JaroslavTulach
Copy link
Member

If still not good, please feel free to send a patch to this PR

More encapsulation in c8b5111. Feel free to go with or without c8b5111 change.

Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unblocking.

@hubertp hubertp merged commit a992c8a into develop Jul 16, 2024
41 checks passed
@hubertp hubertp deleted the wip/hubert/10254-lock-removal branch July 16, 2024 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: No changelog needed Do not require a changelog entry for this PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IllegalMonitorStateException on shutdown
2 participants