-
-
Notifications
You must be signed in to change notification settings - Fork 922
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
Mutex behavior mismatch with MRI since JRuby 9.2.8.0 #5875
Comments
I'm on it! The problem here is that for whatever reason I implemented mutex sleeping to sleep based on some arbitrary lock, rather than on the lock associated with the mutex. |
Seeing this also happen in a Rails app that uses the message_bus gem on JRuby 9.2.8.0. Very similar trace to what @walro posted. Full blocker for being able to upgrade to 9.2.8.0 since we blow up inside the thread handling in that gem |
Circled back to this. Will fix for 9.2.9. |
Ok, finally addressing this. The bug here seems to be that when acquiring a lock held by another thread, we will raise this interrupt error if interrupted. The script you provide needs the main-thread The question is what behavior we should do. If we are attempting to acquire a lock and some other thread forces us to run, do we:
What's correct? |
The other issue here is that in CRuby/MRI, there's no real concurrency around the lock. If the main thread acquires the lock, the other thread will go to sleep. Once the lock is released, the thread will be woken up and proceed to acquire it. There's no scenario where the thread would be waiting for the lock once |
I believe this patch might be the correct behavior. In this case, when the lock acquisition is interrupted, we will loop and try to acquire it again but also check whether any thread events have fired (e.g. kill, raise that would break the thread out of its normal execution path). This means we'll try again to get the lock for this diff --git a/core/src/main/java/org/jruby/ext/thread/Mutex.java b/core/src/main/java/org/jruby/ext/thread/Mutex.java
index 06278320c3..45788d4d13 100644
--- a/core/src/main/java/org/jruby/ext/thread/Mutex.java
+++ b/core/src/main/java/org/jruby/ext/thread/Mutex.java
@@ -95,10 +95,14 @@ public class Mutex extends RubyObject implements DataType {
// try locking without sleep status to avoid looking like blocking
if (!thread.tryLock(lock)) {
- try {
- context.getThread().lockInterruptibly(lock);
- } catch (InterruptedException ex) {
- throw context.runtime.newConcurrencyError("interrupted waiting for mutex");
+ for (;;) {
+ try {
+ context.getThread().lockInterruptibly(lock);
+ return this;
+ } catch (InterruptedException ex) {
+ /// ignore, check thread events and try again!
+ context.pollThreadEvents();
+ }
}
} |
I believe we're experiencing this bug in our rails app. After we upgraded to jRuby 9.2.8.0 our app would just stop responding completely when it was processing many concurrent requests with puma. Thanks for the fix! |
@jboler Sure! Feel free to give a nightly build a try, if you can, to confirm it's all good now. |
Environment
Expected Behavior
The following executes "forever" without errors on MRI 2.5.3 and JRuby 9.2.7.0:
This is a real-world problem cooked down to its core. The real-world app (a busy web-app) uses https://github.com/sharpstone/rack-timeout, where one can find similar mutex usage.
Actual Behavior
After some digging around I would assume this is connected to the change in #5683. What I find a bit curious is that the main thread must also try to synchronize to force the error to happen.
The text was updated successfully, but these errors were encountered: