About 30% of our recent production walkbacks seem to point to a root cause of a destroyed widget being the receiver of a callback. In going though the plethera of walkbacks (usually some form of UndefinedObject not understanding one method or another), the common point I was able to trace back to was the "#callHandlers: with:" method implemented in OSWidget in the PlatformWidgetsFramework sub application.
I thought that if I blocked callbacks to destroyed widgets, that should make my problems go away. I could not think of a valid reason why a callback would need to be executed on a widget that had been destroyed.
So, at the beginning of OsWidget>>#callHandlers: with: , I inserted this line:
owner isDestroyed ifTrue: [ ^self ].
Logic seemed to indicate that if you tested for the destruction of the receiver of the perform of the callback, you would successfully prevent resulting walkbacks. Empirical evidence collected since we moved this change into production indicates a flaw in the logic. Numerous examples of walkbacks have come back showing that the #callHandlers:with: method was executed passing the perform: handlers with:data to owner. And in the very next method, you could see that the label of owner was coming back with "*destroyed".
I am unsure of the flaw in my reasoning. I know there must be a flaw or I would have achieved the desired result.
I am considering changing the test to:
(self isDestroyed or: [owner isDestroyed]) ifTrue: [ ^self ].
I am considering this even though I am "sure" that owner should be the one being tested.
I am also considering adding the line
CwAppContext default asyncExecInUI: [].
I was thinking of adding this right before the test for #isDestroyed. Yes, I would do that with an empty block. I have seem some cases in the base code where this technique was occasionally used and it was an effective tool in helping rid us of the "Invalid operation during callback" walkbacks that plagued us a few years ago.
I have also scoured the old google group for vasmalltalk and the only relevant post I found was this one:
http://groups.google.com/group/ibm.soft ... dd708d334a
This seems to also point to using the asynExecInUI: method. The difference is that you are looking for specific callbacks and applying it to the entire block within. That would be difficult (impossible?) to apply here since there are potentially hundreds of cases of different callbacks. While it would be clear to identifiy which callbacks are failing, it would be more of a challenge to identify the callbacks that should come "first".
Any thoughts on the subject would be welcome.