On 8 October 2012 17:12, Henrik Sperre Johansen
<[email protected]> wrote:
> On 08.10.2012 16:35, Igor Stasenko wrote:
>
> On 8 October 2012 13:41, Henrik Sperre Johansen
> <[email protected]> wrote:
>
> On 08.10.2012 13:25, Igor Stasenko wrote:
>
> On 8 October 2012 13:06, Henrik Sperre Johansen
> <[email protected]> wrote:
>
> On 08.10.2012 13:03, Henrik Sperre Johansen wrote:
>
>
> IMO, lazily checking whether the image has been restarted whenever you
> want to do something stinks.
> Registering to be notified when image starts/stops is a lot better.
>
> Not to mention, less error-prone.
> Miss one session check that the current session is the right one
> somewhere... and everything might blow up if that is the first piece of
> functionality used.
>
> True.
> I did not said that my method should replace old. Sometimes lazy
> initialization is not what you want.
> But having no way to perform lazy initialization is even worse.
>
> Ah, I just objected to the notion that startup lists inherently stinks, and
> took the diametrical view for the sake of argument :)
> Yes, lazy initialization has its uses too, but some guidelines/advice* on
> when to what those uses are, and when you'd use startUp: registration
> instead, is needed I think.
>
> Notice; in most cases where such cleanup at startup is needed (sockets,
> window handles, etc.), additional cleanup is needed when the object goes out
> of scope during regular use, and so a registry usually exist.
>
I will put some more reasons for the sake of discussion & learning.

1. during startup, you have to be very careful about dependencies
between services,
the errors like using uninitialized service(s) makes image
unrecoverable (because VM crashing).
For example , putting 'Transcript show: ' before freetype initialized
may kill an image,
beyond the point of recovery. The hardest part in it, that since
everything is late bound, it sometimes really hard to put
initialization in right order. And loading any new code in image will
also contribute to chaos
of interdependencies, unless all developers know that they should not
use facility A before facility B is properly initialized. And the only
way to do it is to add own checks and one more #startup method,
which 'enabling' your service after all dependencies initialized.
But the problem is that the longer chain of initialization gets, the
more chances that something will go wrong (as well as getting lost in
order of dependencies).

2. garbage collection. Yes, you can walk over weak registry to
invalidate all handles before they having
any chance to be used. Unless during startup, you losing sole
reference to object in registry and then VM triggers GC _before_
entering your startup code. As result , finalization code will attempt
to free non-existing resources.. Which in most cases also leads to VM
crash.

So, i would not agree that using lazy-initialization & check before
use is more error prone than startup :)

> Yes.
>
> Thus, your startup code isn't usually
> X allInstancesDo: #something
> but
> X weakRegistry allEntriesDo: #someting.
>
> which stinks a whole lot less.
>
> in perfect world, yes :)
>
> But world is imperfect..
> For example, look here:
>
> FT2Handle>>shutDown: quitting
>       "we must not save handles (which are pointers) in the image"
>       self clearRegistry.
>       FreeTypeFace allInstances do:[:i |
>               "destroy any faces that are still being referenced"
>               i isValid
>                       ifTrue:[i destroyHandle]].
>       FT2Handle allSubInstances do: [:h | h beNull].  "if some handle was
> not registered"
>
> because of the above, when i pass freetype faces handles to Cairo,
> which caching a lot of stuff inside (obviously for performance reasons),
> when you save an image, and then try to use Cairo after that (like
> rendering text with same font)
> an image is crashing.
> Which means that "we must not save handles (which are pointers) in the
> image" now blocking
> me from having nice interoperability with Cairo..
>
> Needless to say that destroying handles will force their recreation
> after snapshot, since image
> continues running and will keep using freetype fonts.
>
> This is actually the reason why i want to introduce session object(s),
> so that i can fix freetype code
> to play more nicely with cairo library.
>
>
> I agree with this part from the wiki entry:
> "Dolphin does not free external resources on a snapshot. Resources are freed
> on shutdown (by registering for the shutdown events) and pointers/handles
> are cleared on *startup*. Having worked with it for years, I have gone from
> considering it strange to believing it is the correct design."
>
> Rewriting the shutdown to a startUp: method (conditional on the resuming
> parameter) shouldn't be too much work.
>
> A short analysis of the code reveals:
> 1) FT2Face/FT2MemoryFaceData aren't instatiated.
> 2) Both FT2Face and FreeTypeExternalMemory instances are both registered in
> the FT2Handle registry. (if used in a way which instantiates handle)
> 3) FT2Library recreates a new instance based for each call to current, which
> may be problematic, but current return values are never kept, just used to
> check that FT is present.
>
> So really, cleaning the entries found in registry is all that's actually
> needed at startup.
>
> Cheers,
> Henry
>



-- 
Best regards,
Igor Stasenko.

Reply via email to