Re: Deadlock ...
Re: Deadlock ...
- Subject: Re: Deadlock ...
- From: Chuck Hill <email@hidden>
- Date: Mon, 14 May 2007 21:21:14 -0700
On May 14, 2007, at 1:24 PM, Kieran Kelleher wrote:
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.
That probably makes it more of a Wonder list / Mike Schrag question.
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).
Looking at those four threads, I don't see one that looks to be
holding the lock.
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?
I will guess that it would help. Call ec.setSharedEditingContext
(null). Are you using the shared EC at all?
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....
Which strongly points to concurrency and the EOF stack synchronizer
as at least an involved party.
Skip down, the read back up.
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]
6. Something else has the SEC locked for writing so this thread blocks
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
5. The change requires invalidating objects
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
4. There was a change to process:
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
3. lock() processes pending notifications (e.g. from the EOF stack
synchronizer:
WKEditingContext(EOEditingContext)._processNotificationQueue()
line: 4810
2. Dispose locks the ec:
WKEditingContext(EOEditingContext).lock() line: 4688
WKEditingContext(ERXEC).lock() line: 436
1. This is the dispose call:
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
OK, read up from here
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
The above thread is just idling.
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
I will leave that one to Mike. The
ERXObjectStoreCoordinatorSynchronizer is processing a change and
sending notifications. It also needs a write lock on the SEC and
blocks because someone else has it.
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
Late to the party, this one blocks locking the OSC which has been
locked by another thread. I don't see it in the trace, but I am
guessing that ERXObjectStoreCoordinatorSynchronizer has it locked
while it processes the changes.
None of this answers the crucial question: who is holding the SEC
writer lock?
Were there any exceptions that happened before this deadlock?
Chuck
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();
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40global-village.net
This email sent to email@hidden
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden