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

Inner objects inside a class are not singletons #1591

Closed
scabug opened this issue Dec 19, 2008 · 7 comments
Closed

Inner objects inside a class are not singletons #1591

scabug opened this issue Dec 19, 2008 · 7 comments
Assignees

Comments

@scabug
Copy link

scabug commented Dec 19, 2008

It is possible to create several instances of the same inner object in a multithreaded context which may cause inconsistent singleton access.

This is best illustrated on the sample below.

--- Scala ---

abstract class MyType

class InnerObjectTest {
  object unique extends MyType
}

--- javap -private -c -l --

private InnerObjectTest$$unique$$ unique$$module;
...
public final InnerObjectTest$$unique$$ unique();
  Code:
   0:   aload_0
   1:   getfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
   4:   ifnonnull       19
   7:   aload_0
   8:   new     SI-20; //class InnerObjectTest$$unique$$
   11:  dup
   12:  aload_0
   13:  invokespecial   SI-23; //Method InnerObjectTest$$unique$$."<init>":(LInnerObjectTest;)V
   16:  putfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
   19:  aload_0
   20:  getfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
   23:  areturn
 

If you look at the bytecode generated by the compiler, the unique() method initializes a private field named "unique$$module" to a reference to a new instance of type "!InnerObjectTest$$unique$$" but there is no synchronization - if several threads access the 'unique()' method concurrently, there is a small chance that they get different objects.

Object access/initialization code should be the same as lazy val access/initialization code

@scabug
Copy link
Author

scabug commented Dec 19, 2008

Imported From: https://issues.scala-lang.org/browse/SI-1591?orig=1
Reporter: @sbocq
Attachments:

@scabug
Copy link
Author

scabug commented Jun 9, 2010

@hubertp said:
There was a recent discussion on the mailing list whether we should postpone 2.8 release to fix this bug. Given that there is a trivial temporary solution (i.e. using lazy values instead of inner objects) we will postpone fixing this bug until 2.8.1.
I am aware that the bug is important but another long delay in 2.8 is hard to accept.

@scabug
Copy link
Author

scabug commented Sep 22, 2010

@hubertp said:
(In r23059) Closes #1591. Treat nested objects as lazy vals. Updated some tests. Review by dragos

@scabug
Copy link
Author

scabug commented Sep 29, 2010

@hubertp said:
Reverted, because it is causing #3879.

@scabug
Copy link
Author

scabug commented Oct 1, 2010

@hubertp said:
Fixed in r23164.

@scabug scabug closed this as completed May 18, 2011
@scabug
Copy link
Author

scabug commented Jul 19, 2011

Martin Kneissl (mkneissl) said:
Looking at the byte code generated by Scala 2.8.1.final, it seems that this bug has not been fixed or reoccurred after the above commit.
Inner objects in 2.8.1.final are NOT singletons in multi-threaded environments.

2.9.0-1 looks ok.

@scabug
Copy link
Author

scabug commented Jul 20, 2011

Martin Kneissl (mkneissl) said:
Test program to reproduce this bug.

See also https://github.com/mkneissl/scalabugs/blob/master/src/main/scala/eu/kneissl/scalabugs/InnerObjectInitialization.scala

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants