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

Deadlock in DateTimeZone/FixedDateTimeZone static initialization #171

Closed
david-at-aws opened this issue Sep 2, 2014 · 2 comments
Closed

Comments

@david-at-aws
Copy link

We've got a user reporting a deadlock while using the AWS SDK for Java. The user is calling into two different parts of the SDK from two different threads. One ends up accessing DateTimeZone.UTC while the other ends up directly creating a new FixedDateTimeZone.

Thread 1 grabs a lock on DateTimeZone to run its static initialization block. Thread 2 grabs a lock on FixedDateTimeZone to run its static initialization block. FixedDateTimeZone extends DateTimeZone, so the first thing Thread 2 does is try to grab a lock on DateTimeZone to see if it has been initialized yet. Meanwhile, Thread 1 attempts to grab a lock on FixedDateTimeZone to see if it has been initialized yet because the static initializer creates an instance of FixedDateTimeZone to assign to DateTimeZone.UTC. Boom, deadlock.

Minimal repro code:

import org.joda.time.DateTimeZone;
import org.joda.time.tz.FixedDateTimeZone;

public class Test {
    public static void main(String[] args) {
        Thread one = new Thread() {
            @Override
            public void run() {
                DateTimeZone zone = DateTimeZone.UTC;
            }
        };

        Thread two = new Thread() {
            @Override
            public void run() {
                new FixedDateTimeZone("GMT", "GMT", 0, 0);
            }
        };

        one.start();
        two.start();
    }
}

deadlocks pretty reliably for me with:

"Thread-1" prio=10 tid=0x0a01a800 nid=0xbfb in Object.wait() [0x6db8d000]
   java.lang.Thread.State: RUNNABLE
        at Test$2.run(Test.java:16)

"Thread-0" prio=10 tid=0x0a019000 nid=0xbfa in Object.wait() [0x6dbde000]
   java.lang.Thread.State: RUNNABLE
        at org.joda.time.DateTimeZone.<clinit>(DateTimeZone.java:95)
        at Test$1.run(Test.java:9)

Is this something that other people have run into? I can certainly work around it by adding no-op references to DateTimeZone before creating any FixedDateTimeZone instances, but that seems awfully fragile (and in particular doesn't protect against something else in my users' processes directly referencing FixedDateTimeZone and locking in the other direction). Any other recommendations? Unfortunately, there doesn't seem to be a straightforward way of fixing this in JodaTime without breaking DateTimeZone.UTC...

@jodastephen
Copy link
Member

Please verify the change works for you. AFAICT, it is backwards compatible, but if you think it isn't please let me know.

@david-at-aws
Copy link
Author

Thanks Stephen! As expected, I can no longer reproduce the deadlock after the change. We don't depend on DateTimeZone.UTC being a FixedDateTimeZone (or equal to other FixedDateTimeZones with the same id and offsets), so no problem there either at least for us.

Guardiola31337 pushed a commit to Guardiola31337/joda-time that referenced this issue Sep 25, 2015
Referencing DateTimeZone and FixedDateTimeZone from two
threads at startup could deadlock
Add package scoped UTCDateTimeZone class to avoid this

DateTimeZone.UTC has changed implementation type
It used to be a FixedDateTimeZone
Now it is a UTCDateTimeZone
This avoids a potential deadlock scenario
Serialization is unaffected
This change will only be observable if you cast the
UTC constant to FixedDateTimeZone
Fixes JodaOrg#171
borja pushed a commit to Guardiola31337/joda-time that referenced this issue Feb 8, 2016
Referencing DateTimeZone and FixedDateTimeZone from two
threads at startup could deadlock
Add package scoped UTCDateTimeZone class to avoid this

DateTimeZone.UTC has changed implementation type
It used to be a FixedDateTimeZone
Now it is a UTCDateTimeZone
This avoids a potential deadlock scenario
Serialization is unaffected
This change will only be observable if you cast the
UTC constant to FixedDateTimeZone
Fixes JodaOrg#171
borja pushed a commit to Guardiola31337/joda-time that referenced this issue Feb 8, 2016
Referencing DateTimeZone and FixedDateTimeZone from two
threads at startup could deadlock
Add package scoped UTCDateTimeZone class to avoid this

DateTimeZone.UTC has changed implementation type
It used to be a FixedDateTimeZone
Now it is a UTCDateTimeZone
This avoids a potential deadlock scenario
Serialization is unaffected
This change will only be observable if you cast the
UTC constant to FixedDateTimeZone
Fixes JodaOrg#171
Guardiola31337 pushed a commit to Guardiola31337/joda-time that referenced this issue Feb 8, 2016
Referencing DateTimeZone and FixedDateTimeZone from two
threads at startup could deadlock
Add package scoped UTCDateTimeZone class to avoid this

DateTimeZone.UTC has changed implementation type
It used to be a FixedDateTimeZone
Now it is a UTCDateTimeZone
This avoids a potential deadlock scenario
Serialization is unaffected
This change will only be observable if you cast the
UTC constant to FixedDateTimeZone
Fixes JodaOrg#171
Guardiola31337 pushed a commit to Guardiola31337/joda-time that referenced this issue Feb 8, 2016
Referencing DateTimeZone and FixedDateTimeZone from two
threads at startup could deadlock
Add package scoped UTCDateTimeZone class to avoid this

DateTimeZone.UTC has changed implementation type
It used to be a FixedDateTimeZone
Now it is a UTCDateTimeZone
This avoids a potential deadlock scenario
Serialization is unaffected
This change will only be observable if you cast the
UTC constant to FixedDateTimeZone
Fixes JodaOrg#171
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants