http://bugs.winehq.org/show_bug.cgi?id=4436
------- Additional Comments From J.A.Gow@furrybubble.co.uk 2006-13-02 07:25 ------- Nice ASCII art :)
This is close to what I had in mind, but the problem I found was to ensure that well-behaved apps (i.e. ones that correctly call IStream_Release before IStorage_Release) worked as well as badly behaved ones (that called IStorage_Release and expected all streams to be closed and destroyed at this time) without either creating an object leak.
As I see it this requires the following behaviour:
We maintain the list of stream objects in the storage object. When the storage destructor is called, before killing the storage object we iterate the list of stream objects. If any are left (badly behaved app) we kill them by calling the IStream destructor for each object in the list, before killing the storage object.
Now this is OK, except for the case of a well behaved app that correctly calls the stream object destructor before the storage object destructor. In this case, the stream object destructor will have to inform the storage object that the stream object should be removed from the list of stream objects maintained by the storage object. If the stream object is not removed from the list, when the storage object destructor is called it will attempt to kill the already-destroyed stream object when it finds it in the list. Hey presto- segfault!.
So we need an interface by which a stream object can communicate its imminent destruction to the storage object in which it lives - the direction of communication would be stream object -> storage object.
And it is here where I am not sure how to proceed. I have the list management stuff coded in the storage object but I need advice on how best to introduce an interface for communication between a stream object destructor and the storage object in which it resides.
In your suggestion, it seems that we are not killing the outstanding stream objects when the outstanding Storage objects are destroyed. Surely this would guarantee a memory leak for a badly behaved app? Since it would seem no app would explicitly destroy the stream object and then afterwards try and use the streams created within it during its scope, would it not make more sense to kill outstanding streams with closure of the storage object and avoid the memory leak? I agree it breaks the object rules somewhat, but then it looks like Windows does too!