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 [EMAIL PROTECTED]) 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 [EMAIL PROTECTED] (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 protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/chill% 40global-village.net

This email sent to [EMAIL PROTECTED]

--

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 protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to