I was running pre-deployment tests on code which had not itself been changed and I got a deadlock. The only app change that I can think that might be affecting this is the fact that I have the EOF stack synchronizer turned on in this latest release of the app. The deadlock happened when I called dispose on an ec that was created for a very short time to make and save some changes. Suspending all threads and looking at stack traces reveals four threads in a wait state (stack traces shown below). The unchanged offending code is shown below the 4 stack traces. At the time, my app was on a long response page and the background thread (Thread [wk.cheetah.ShipRtbsCampaignsLRTask@640285]) hung when calling dispose on an editing context.
BTW, I see there is a EOSharedEditingContext lock in the first stack trace below, what has that got to do with my ec being locked ...... I recall discussion on the list about EOShared EC being bad and to "turn it off" .... would turning it off help and if so, how can I turn it off?
The difficult part is that I can stop the app, run it again and I cannot reproduce this again right now with no code changes....
Any suggestions on how to prevent this and make my code more robust?
Thread [wk.cheetah.ShipRtbsCampaignsLRTask@640285] (Suspended)
Object.wait(long) line: not available [native method]
NSMultiReaderLock$ConditionLock(Object).wait() line: 474
NSMultiReaderLock$ConditionLock.await() line: 506
NSMultiReaderLock._lockForWriting() line: 204
NSMultiReaderLock.lockForWriting() line: 165
EOSharedEditingContext.lock() line: 700
WKEditingContext(EOEditingContext).lockObjectStore() line: 4733
WKEditingContext(EOEditingContext).refaultObject(EOEnterpriseObject, EOGlobalID, EOEditingContext) line: 4041
WKEditingContext(ERXEC).refaultObject(EOEnterpriseObject, EOGlobalID, EOEditingContext) line: 1064
WKEditingContext(EOEditingContext)._refaultObjectWithGlobalID(EOEnterpriseObject, EOGlobalID) line: 3293
WKEditingContext(EOEditingContext)._newChangesFromInvalidatingObjectsWithGlobalIDs(NSArray) line: 3522
WKEditingContext(EOEditingContext)._processObjectStoreChanges(NSDictionary) line: 3558
GeneratedMethodAccessor373.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 585
NSSelector.invoke(Object, Object[]) line: 354
NSSelector._safeInvokeSelector(NSSelector, Object, Object[]) line: 108
WKEditingContext(EOEditingContext)._processNotificationQueue() line: 4810
WKEditingContext(EOEditingContext).lock() line: 4688
WKEditingContext(ERXEC).lock() line: 436
WKEditingContext(EOEditingContext)._dispose(boolean) line: 1064
WKEditingContext(EOEditingContext).dispose() line: 1059
WKEditingContext(ERXEC).dispose() line: 574
ShipRtbsCampaignsLRTask.performAction() line: 97
ShipRtbsCampaignsLRTask(ERXLongResponseTask$DefaultImplementation).run() line: 163
ERXLongResponseTask$WorkerThread(Thread).run() line: 613
ERXLongResponseTask$WorkerThread.run() line: 60
Thread [ProcessChangesQueue] (Suspended)
Object.wait(long) line: not available [native method]
_WORunLoop._acceptInputBeforeDate(NSTimestamp) line: 217
_WORunLoop.runBeforeDate(NSTimestamp) line: 71
Application(WOApplication)._runOnce() line: 775
Application(WOApplication).run() line: 900
Application(ERXApplication).run() line: 660
WOApplication.main(String[], Class) line: 324
ERXApplication.main(String[], Class) line: 333
Application.main(String[]) line: 81
Thread [Thread-1] (Suspended)
Object.wait(long) line: not available [native method]
NSMultiReaderLock$ConditionLock(Object).wait() line: 474
NSMultiReaderLock$ConditionLock.await() line: 506
NSMultiReaderLock._lockForWriting() line: 204
NSMultiReaderLock.lockForWriting() line: 165
EOSharedEditingContext.lock() line: 700
WKEditingContext(EOEditingContext).lockObjectStore() line: 4733
WKEditingContext(EOEditingContext)._processReferenceQueue() line: 4829
WKEditingContext(EOEditingContext)._processRecentChanges() line: 1930
WKEditingContext(EOEditingContext).processRecentChanges() line: 1951
WKEditingContext(ERXEC).processRecentChanges() line: 623
WKEditingContext(EOEditingContext)._processObjectStoreChanges(NSDictionary) line: 3536
GeneratedMethodAccessor373.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 585
NSSelector.invoke(Object, Object[]) line: 354
NSSelector._safeInvokeSelector(NSSelector, Object, Object[]) line: 108
WKEditingContext(EOEditingContext)._processNotificationQueue() line: 4810
WKEditingContext(EOEditingContext).lock() line: 4688
WKEditingContext(ERXEC).lock() line: 436
WKEditingContext(EOEditingContext).tryLock() line: 4700
WKEditingContext(EOEditingContext)._sendOrEnqueueNotification(NSNotification, NSSelector) line: 4774
WKEditingContext(EOEditingContext)._objectsChangedInStore(NSNotification) line: 3598
WKEditingContext(ERXEC)._objectsChangedInStore(NSNotification) line: 1241
GeneratedMethodAccessor372.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 585
NSSelector._safeInvokeMethod(Method, Object, Object[]) line: 120
NSNotificationCenter$_Entry.invokeMethod(NSNotification) line: 601
NSNotificationCenter.postNotification(NSNotification) line: 545
NSNotificationCenter.postNotification(String, Object, NSDictionary) line: 575
EOObjectStoreCoordinator._objectsChangedInSubStore(NSNotification) line: 744
GeneratedMethodAccessor376.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 585
NSSelector._safeInvokeMethod(Method, Object, Object[]) line: 120
NSNotificationCenter$_Entry.invokeMethod(NSNotification) line: 601
NSNotificationCenter.postNotification(NSNotification) line: 545
NSNotificationCenter.postNotification(String, Object, NSDictionary) line: 575
ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue$InsertSnapshotProcessor.processSnapshots(EODatabaseContext, EODatabase, NSDictionary) line: 273
ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue._process(EOObjectStoreCoordinator, EOObjectStoreCoordinator, NSMutableDictionary, ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue$SnapshotProcessor, NSDictionary, String) line: 432
ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue.process(EOObjectStoreCoordinator, ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue$SnapshotProcessor, NSDictionary, String) line: 450
ERXObjectStoreCoordinatorSynchronizer$ProcessChangesQueue.run() line: 524
Thread.run() line: 613
Thread [WorkerThread3] (Suspended)
Object.wait(long) line: not available [native method]
NSRecursiveLock(Object).wait() line: 474
NSRecursiveLock.lock() line: 72
EOObjectStoreCoordinator.lock() line: 466
WKEditingContext(EOEditingContext).lockObjectStore() line: 4735
WKEditingContext(EOEditingContext)._processReferenceQueue() line: 4829
WKEditingContext(EOEditingContext)._processRecentChanges() line: 1930
WKEditingContext(EOEditingContext).processRecentChanges() line: 1951
WKEditingContext(ERXEC).processRecentChanges() line: 623
WKEditingContext(EOEditingContext)._processObjectStoreChanges(NSDictionary) line: 3536
GeneratedMethodAccessor373.invoke(Object, Object[]) line: not available
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 585
NSSelector.invoke(Object, Object[]) line: 354
NSSelector._safeInvokeSelector(NSSelector, Object, Object[]) line: 108
WKEditingContext(EOEditingContext)._processNotificationQueue() line: 4810
WKEditingContext(EOEditingContext).lock() line: 4688
WKEditingContext(ERXEC).lock() line: 436
Session(WOSession)._awakeInContext(WOContext) line: 717
Application(WOApplication).restoreSessionWithID(String, WOContext) line: 1550
Application(ERXApplication).restoreSessionWithID(String, WOContext) line: 1335
WOComponentRequestHandler._dispatchWithPreparedApplication(WOApplication, WOContext, NSDictionary) line: 314
WOComponentRequestHandler._handleRequest(WORequest) line: 358
WOComponentRequestHandler.handleRequest(WORequest) line: 432
Application(WOApplication).dispatchRequest(WORequest) line: 1306
Application(ERXApplication).dispatchRequest(WORequest) line: 1117
Application.dispatchRequest(WORequest) line: 195
WOWorkerThread.runOnce() line: 173
WOWorkerThread.run() line: 254
Thread.run() line: 613
EOEditingContext ec = WKEditingContext.createInstance( objectStore() );
ec.lock();
// Prevents excessive queries when creating ship messages.
ec.setFetchTimestamp( fetchTimestamp );
CTCampaign localCampaign = null;
try {
localCampaign = (CTCampaign)EOUtilities.localInstanceOfObject( ec, campaign );
// Ship it
localCampaign.shipMessages();
localCampaign.editingContext().saveChanges();
}
catch ( Exception exception) {
log.error( "Exception while shipping " + localCampaign.toLongString(), exception );
}
finally {
ec.unlock();
ec.dispose();
}