Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 266982 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java (+2 lines)
Lines 41-46 Link Here
41
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_260764_Test;
41
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_260764_Test;
42
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_261218_Test;
42
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_261218_Test;
43
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_265114_Test;
43
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_265114_Test;
44
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_266982_Test;
44
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
45
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
45
import org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite;
46
import org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite;
46
47
Lines 128-133 Link Here
128
    testClasses.add(Bugzilla_260764_Test.class);
129
    testClasses.add(Bugzilla_260764_Test.class);
129
    testClasses.add(Bugzilla_261218_Test.class);
130
    testClasses.add(Bugzilla_261218_Test.class);
130
    testClasses.add(Bugzilla_265114_Test.class);
131
    testClasses.add(Bugzilla_265114_Test.class);
132
    testClasses.add(Bugzilla_266982_Test.class);
131
133
132
    // TODO testClasses.add(NonCDOResourceTest.class);
134
    // TODO testClasses.add(NonCDOResourceTest.class);
133
    // TODO testClasses.add(GeneratedEcoreTest.class);
135
    // TODO testClasses.add(GeneratedEcoreTest.class);
(-)src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_266982_Test.java (+85 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *    Simon McDuff - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.tests.bugzilla;
12
13
import org.eclipse.emf.cdo.eresource.CDOResource;
14
import org.eclipse.emf.cdo.session.CDOSession;
15
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
16
import org.eclipse.emf.cdo.tests.model1.Customer;
17
import org.eclipse.emf.cdo.transaction.CDOTransaction;
18
import org.eclipse.emf.cdo.util.CDOUtil;
19
20
import junit.framework.Assert;
21
22
/**
23
 * IllegalStateException in CDOStore.getRevision
24
 * <p>
25
 * See https://bugs.eclipse.org/266982
26
 * 
27
 * @author Simon McDuff
28
 */
29
public class Bugzilla_266982_Test extends AbstractCDOTest
30
{
31
  public void testBugzilla_266982() throws Exception
32
  {
33
    final Customer customer = getModel1Factory().createCustomer();
34
    final boolean done[] = new boolean[1];
35
    final Exception exception[] = new Exception[1];
36
    done[0] = false;
37
    customer.setName("customer");
38
39
    CDOSession session = openModel1Session();
40
    CDOTransaction transaction = session.openTransaction();
41
    CDOResource resource = transaction.createResource("/test1");
42
    resource.getContents().add(customer);
43
44
    transaction.commit();
45
46
    Runnable changeObjects = new Runnable()
47
    {
48
49
      public void run()
50
      {
51
        try
52
        {
53
          CDOSession session = openModel1Session();
54
          CDOTransaction transaction = session.openTransaction();
55
          Customer customerToLoad = (Customer)transaction.getObject(CDOUtil.getCDOObject(customer).cdoID());
56
          while (!done[0])
57
          {
58
            // Could fail if the attach is not thread safe
59
            customerToLoad.getName();
60
          }
61
          transaction.close();
62
          session.close();
63
        }
64
        catch (Exception ex)
65
        {
66
          exception[0] = ex;
67
        }
68
      }
69
    };
70
    new Thread(changeObjects).start();
71
72
    for (int i = 0; i < 500 && exception[0] == null; i++)
73
    {
74
      customer.setName("Ottawa" + i);
75
      transaction.commit();
76
    }
77
    done[0] = true;
78
    if (exception[0] != null)
79
    {
80
      exception[0].printStackTrace();
81
      Assert.fail(exception[0].getMessage());
82
    }
83
    session.close();
84
  }
85
}
(-)src/org/eclipse/emf/internal/cdo/CDOStateMachine.java (-62 / +150 lines)
Lines 177-189 Link Here
177
   */
177
   */
178
  public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
178
  public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
179
  {
179
  {
180
    List<InternalCDOObject> contents = new ArrayList<InternalCDOObject>();
180
    try
181
    attach1(object, new Pair<InternalCDOTransaction, List<InternalCDOObject>>(transaction, contents));
181
    {
182
    attach2(object);
182
      transaction.getStateLock().lock();
183
      List<InternalCDOObject> contents = new ArrayList<InternalCDOObject>();
184
      attach1(object, new Pair<InternalCDOTransaction, List<InternalCDOObject>>(transaction, contents));
185
      attach2(object);
183
186
184
    for (InternalCDOObject content : contents)
187
      for (InternalCDOObject content : contents)
188
      {
189
        attach2(content);
190
      }
191
    }
192
    finally
185
    {
193
    {
186
      attach2(content);
194
      transaction.getStateLock().unlock();
187
    }
195
    }
188
  }
196
  }
189
197
Lines 219-253 Link Here
219
   */
227
   */
220
  public void detach(InternalCDOObject object)
228
  public void detach(InternalCDOObject object)
221
  {
229
  {
222
    if (TRACER.isEnabled())
230
    InternalCDOView view = object.cdoView();
231
232
    try
223
    {
233
    {
224
      trace(object, CDOEvent.DETACH);
234
      view.getStateLock().lock();
225
    }
235
236
      if (TRACER.isEnabled())
237
      {
238
        trace(object, CDOEvent.DETACH);
239
      }
226
240
227
    List<InternalCDOObject> objectsToDetach = new ArrayList<InternalCDOObject>();
241
      List<InternalCDOObject> objectsToDetach = new ArrayList<InternalCDOObject>();
228
    InternalCDOTransaction transaction = (InternalCDOTransaction)object.cdoView();
242
      InternalCDOTransaction transaction = (InternalCDOTransaction)object.cdoView();
229
243
230
    // Accumulate objects that needs to be detached
244
      // Accumulate objects that needs to be detached
231
    // If we have an error, we will keep the graph exactly like it was before.
245
      // If we have an error, we will keep the graph exactly like it was before.
232
    process(object, CDOEvent.DETACH, objectsToDetach);
246
      process(object, CDOEvent.DETACH, objectsToDetach);
233
247
234
    // postDetach requires the object to be TRANSIENT
248
      // postDetach requires the object to be TRANSIENT
235
    for (InternalCDOObject content : objectsToDetach)
249
      for (InternalCDOObject content : objectsToDetach)
236
    {
250
      {
237
      CDOState oldState = content.cdoInternalSetState(CDOState.TRANSIENT);
251
        CDOState oldState = content.cdoInternalSetState(CDOState.TRANSIENT);
238
      content.cdoInternalPostDetach();
252
        content.cdoInternalPostDetach();
239
      content.cdoInternalSetState(oldState);
253
        content.cdoInternalSetState(oldState);
240
    }
254
      }
241
255
242
    // detachObject needs to know the state before we change the object to TRANSIENT
256
      // detachObject needs to know the state before we change the object to TRANSIENT
243
    for (InternalCDOObject content : objectsToDetach)
257
      for (InternalCDOObject content : objectsToDetach)
244
    {
258
      {
245
      transaction.detachObject(content);
259
        transaction.detachObject(content);
246
      content.cdoInternalSetState(CDOState.TRANSIENT);
260
        content.cdoInternalSetState(CDOState.TRANSIENT);
247
261
248
      content.cdoInternalSetView(null);
262
        content.cdoInternalSetView(null);
249
      content.cdoInternalSetID(null);
263
        content.cdoInternalSetID(null);
250
      content.cdoInternalSetRevision(null);
264
        content.cdoInternalSetRevision(null);
265
      }
266
    }
267
    finally
268
    {
269
      view.getStateLock().unlock();
251
    }
270
    }
252
  }
271
  }
253
272
Lines 256-267 Link Here
256
   */
275
   */
257
  public void read(InternalCDOObject object)
276
  public void read(InternalCDOObject object)
258
  {
277
  {
259
    if (TRACER.isEnabled())
278
    InternalCDOView view = object.cdoView();
279
280
    try
260
    {
281
    {
261
      trace(object, CDOEvent.READ);
282
      view.getStateLock().lock();
262
    }
283
      if (TRACER.isEnabled())
284
      {
285
        trace(object, CDOEvent.READ);
286
      }
263
287
264
    process(object, CDOEvent.READ, null);
288
      process(object, CDOEvent.READ, null);
289
    }
290
    finally
291
    {
292
      view.getStateLock().unlock();
293
    }
265
  }
294
  }
266
295
267
  /**
296
  /**
Lines 277-288 Link Here
277
   */
306
   */
278
  public void write(InternalCDOObject object, CDOFeatureDelta featureDelta)
307
  public void write(InternalCDOObject object, CDOFeatureDelta featureDelta)
279
  {
308
  {
280
    if (TRACER.isEnabled())
309
    InternalCDOView view = object.cdoView();
310
311
    try
281
    {
312
    {
282
      trace(object, CDOEvent.WRITE);
313
      view.getStateLock().lock();
283
    }
314
      if (TRACER.isEnabled())
315
      {
316
        trace(object, CDOEvent.WRITE);
317
      }
284
318
285
    process(object, CDOEvent.WRITE, featureDelta);
319
      process(object, CDOEvent.WRITE, featureDelta);
320
    }
321
    finally
322
    {
323
      view.getStateLock().unlock();
324
    }
286
  }
325
  }
287
326
288
  /**
327
  /**
Lines 321-341 Link Here
321
360
322
    if (view != null)
361
    if (view != null)
323
    {
362
    {
324
      InternalCDOSession session = (InternalCDOSession)view.getSession();
363
      try
325
      revisions = session.getSessionProtocol().verifyRevision(revisions);
326
327
      revisions.addAll(revised);
328
      for (InternalCDORevision revision : revisions)
329
      {
364
      {
330
        InternalCDOObject object = ids.get(revision.getID());
365
        ((InternalCDOView)view).getStateLock().lock();
331
        if (TRACER.isEnabled())
366
        InternalCDOSession session = (InternalCDOSession)view.getSession();
367
        revisions = session.getSessionProtocol().verifyRevision(revisions);
368
369
        revisions.addAll(revised);
370
        for (InternalCDORevision revision : revisions)
332
        {
371
        {
333
          trace(object, CDOEvent.RELOAD);
372
          InternalCDOObject object = ids.get(revision.getID());
334
        }
373
          if (TRACER.isEnabled())
374
          {
375
            trace(object, CDOEvent.RELOAD);
376
          }
335
377
336
        process(object, CDOEvent.RELOAD, null);
378
          process(object, CDOEvent.RELOAD, null);
379
        }
380
      }
381
      finally
382
      {
383
        ((InternalCDOView)view).getStateLock().unlock();
337
      }
384
      }
338
    }
385
    }
386
339
  }
387
  }
340
388
341
  /**
389
  /**
Lines 343-354 Link Here
343
   */
391
   */
344
  public void invalidate(InternalCDOObject object, int version)
392
  public void invalidate(InternalCDOObject object, int version)
345
  {
393
  {
346
    if (TRACER.isEnabled())
394
    InternalCDOView view = object.cdoView();
395
396
    try
347
    {
397
    {
348
      trace(object, CDOEvent.INVALIDATE);
398
      view.getStateLock().lock();
349
    }
399
      if (TRACER.isEnabled())
400
      {
401
        trace(object, CDOEvent.INVALIDATE);
402
      }
350
403
351
    process(object, CDOEvent.INVALIDATE, version);
404
      process(object, CDOEvent.INVALIDATE, version);
405
    }
406
    finally
407
    {
408
      view.getStateLock().unlock();
409
    }
352
  }
410
  }
353
411
354
  /**
412
  /**
Lines 356-367 Link Here
356
   */
414
   */
357
  public void detachRemote(InternalCDOObject object)
415
  public void detachRemote(InternalCDOObject object)
358
  {
416
  {
359
    if (TRACER.isEnabled())
417
    InternalCDOView view = object.cdoView();
418
419
    try
360
    {
420
    {
361
      trace(object, CDOEvent.DETACH_REMOTE);
421
      view.getStateLock().lock();
362
    }
422
      if (TRACER.isEnabled())
423
      {
424
        trace(object, CDOEvent.DETACH_REMOTE);
425
      }
363
426
364
    process(object, CDOEvent.DETACH_REMOTE, CDORevision.UNSPECIFIED_VERSION);
427
      process(object, CDOEvent.DETACH_REMOTE, CDORevision.UNSPECIFIED_VERSION);
428
    }
429
    finally
430
    {
431
      view.getStateLock().unlock();
432
    }
365
  }
433
  }
366
434
367
  /**
435
  /**
Lines 369-380 Link Here
369
   */
437
   */
370
  public void commit(InternalCDOObject object, CommitTransactionResult result)
438
  public void commit(InternalCDOObject object, CommitTransactionResult result)
371
  {
439
  {
372
    if (TRACER.isEnabled())
440
    InternalCDOView view = object.cdoView();
441
442
    try
373
    {
443
    {
374
      trace(object, CDOEvent.COMMIT);
444
      view.getStateLock().lock();
375
    }
445
      if (TRACER.isEnabled())
446
      {
447
        trace(object, CDOEvent.COMMIT);
448
      }
376
449
377
    process(object, CDOEvent.COMMIT, result);
450
      process(object, CDOEvent.COMMIT, result);
451
    }
452
    finally
453
    {
454
      view.getStateLock().unlock();
455
    }
378
  }
456
  }
379
457
380
  /**
458
  /**
Lines 382-393 Link Here
382
   */
460
   */
383
  public void rollback(InternalCDOObject object)
461
  public void rollback(InternalCDOObject object)
384
  {
462
  {
385
    if (TRACER.isEnabled())
463
    InternalCDOView view = object.cdoView();
464
465
    try
386
    {
466
    {
387
      trace(object, CDOEvent.ROLLBACK);
467
      view.getStateLock().lock();
388
    }
468
      if (TRACER.isEnabled())
469
      {
470
        trace(object, CDOEvent.ROLLBACK);
471
      }
389
472
390
    process(object, CDOEvent.ROLLBACK, null);
473
      process(object, CDOEvent.ROLLBACK, null);
474
    }
475
    finally
476
    {
477
      view.getStateLock().unlock();
478
    }
391
  }
479
  }
392
480
393
  @Override
481
  @Override
(-)src/org/eclipse/emf/internal/cdo/CDOStore.java (-2 / +10 lines)
Lines 566-573 Link Here
566
566
567
  private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
567
  private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
568
  {
568
  {
569
    CDOStateMachine.INSTANCE.read(cdoObject);
569
    try
570
    return getRevision(cdoObject);
570
    {
571
      cdoObject.cdoView().getStateLock().lock();
572
      CDOStateMachine.INSTANCE.read(cdoObject);
573
      return getRevision(cdoObject);
574
    }
575
    finally
576
    {
577
      cdoObject.cdoView().getStateLock().unlock();
578
    }
571
  }
579
  }
572
580
573
  private static InternalCDORevision getRevisionForWriting(InternalCDOObject cdoObject, CDOFeatureDelta delta)
581
  private static InternalCDORevision getRevisionForWriting(InternalCDOObject cdoObject, CDOFeatureDelta delta)
(-)src/org/eclipse/emf/spi/cdo/InternalCDOView.java (+6 lines)
Lines 30-35 Link Here
30
30
31
import java.util.Collection;
31
import java.util.Collection;
32
import java.util.Set;
32
import java.util.Set;
33
import java.util.concurrent.locks.ReentrantLock;
33
34
34
/**
35
/**
35
 * @author Eike Stepper
36
 * @author Eike Stepper
Lines 98-101 Link Here
98
  public void unsubscribe(EObject eObject, Adapter adapter);
99
  public void unsubscribe(EObject eObject, Adapter adapter);
99
100
100
  public boolean hasSubscription(CDOID id);
101
  public boolean hasSubscription(CDOID id);
102
103
  /**
104
   * Used to attach and detach EObject with the corresponding CDORevision
105
   */
106
  public ReentrantLock getStateLock();
101
}
107
}
(-)src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java (+10 lines)
Lines 125-130 Link Here
125
125
126
  private ReentrantLock lock = new ReentrantLock(true);
126
  private ReentrantLock lock = new ReentrantLock(true);
127
127
128
  private ReentrantLock stateLock = new ReentrantLock(true);
129
128
  private CDOResourceImpl rootResource;
130
  private CDOResourceImpl rootResource;
129
131
130
  private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager();
132
  private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager();
Lines 260-265 Link Here
260
  }
262
  }
261
263
262
  /**
264
  /**
265
   * @since 2.0
266
   */
267
  public ReentrantLock getStateLock()
268
  {
269
    return lock;
270
  }
271
272
  /**
263
   * @throws InterruptedException
273
   * @throws InterruptedException
264
   * @since 2.0
274
   * @since 2.0
265
   */
275
   */

Return to bug 266982