diff --git a/openide.loaders/src/org/openide/loaders/DataObject.java b/openide.loaders/src/org/openide/loaders/DataObject.java --- a/openide.loaders/src/org/openide/loaders/DataObject.java +++ b/openide.loaders/src/org/openide/loaders/DataObject.java @@ -129,9 +129,12 @@ * objects. It is static and shared among all DataObjects. */ private static final Object listenersMethodLock = new Object(); - - /** Lock used for ensuring there will be just one node delegate */ - private final Object nodeCreationLock = new Object(); + + /** + * Does not guarantee that {@link #createNodeDelegate} will be called only once. + * But does guarantee that only one resulting node will actually be used. + */ + private final static Object NODE_CREATION_LOCK = new Object(); /** Lock for copy/move/rename/etc. operations */ private static Object synchObject = new Object (); @@ -274,26 +277,18 @@ } private final Node getNodeDelegateImpl() { - if (nodeDelegate == null) { - // synchronize on something private, so only one delegate can be created - // do not synchronize on this, because we could deadlock with - // subclasses could synchronize too. - Children.MUTEX.readAccess (new Runnable() { - public void run() { - synchronized(nodeCreationLock) { - if (nodeDelegate == null) { - nodeDelegate = createNodeDelegate(); - } - } + if (getNodeDelegateOrNull() == null) { + Node _nodeDelegate = createNodeDelegate(); + if (_nodeDelegate == null) { + throw new IllegalStateException(this + " has null node delegate"); // NOI18N + } + synchronized (NODE_CREATION_LOCK) { + if (nodeDelegate == null) { + nodeDelegate = _nodeDelegate; } - }); - - // JST: debuging code - if (nodeDelegate == null) { - throw new IllegalStateException("DataObject " + this + " has null node delegate"); // NOI18N } } - return nodeDelegate; + return getNodeDelegateOrNull(); } /** This method allows DataFolder to filter its nodes. @@ -310,11 +305,15 @@ * @return node delegate or null */ final Node getNodeDelegateOrNull () { - return nodeDelegate; + synchronized (NODE_CREATION_LOCK) { + return nodeDelegate; + } } final void setNodeDelegate(Node n) { - nodeDelegate = n; + synchronized (NODE_CREATION_LOCK) { + nodeDelegate = n; + } } /** Provides node that should represent this data object.