Stanley M. Ho wrote:
Hi Bryan,

Bryan Atsatt wrote:
Sorry, but this makes no sense to me. When a module transitions from
RESOLVED to READY, it is, by definition, prepared to execute any of its
code, including calls into dependent  modules. And this is true even in
the case of cyclic dependencies; otherwise, we could not hand out a
module for use at this point either!

So all we have to do is call initialize() as the last step before
transitioning to READY. If it fails, we go to ERROR, else go to READY.

I'm afraid it's more complicated than that. Even if a module is in
resolved state, the imported modules might still be in the middle of
initialization. The question is when a module's initializer is called,
what kind of state do we expect its imported modules to be in?

I think the semantic we want is that the imported modules should have
been initialized (meaning their initializers should have been called)
when the current module's initializer is invoked, so we won't run into
weird situations where the imported modules are only half-initialized
when they are accessed by the importer's initializer. However, when
cyclic dependencies are involved, I don't think we can support this
semantic for all imported modules.

This was why I suggested when an initializer in a module attempts to
access the imported modules, we make no guarantee that *all* imported
modules are fully initialized and accessible in all situations. In other
words, we can only guarantee that the initializer can access those
imported modules that are fully initialized at that point.

I agree (this is the order-of-static-initialization type problem I
referred to earlier).

We definitely need to document this with some care. But, again, the only
real potential issue here is with cycles, just as it is during
initialization. In the absence of cycles, the release() calls will occur
in the correct order, right? That is, if

  A --depends--> B --depends--> C

And C is released, the importers will be released first: A, then B, and
finally C.

Sounds right.

As long as we guarantee this ordering, the potential issues will be
reduced to those due to cycles. And, again, just as with
order-of-static-initialization, developers must be aware of the pitfalls
of cycles and code around them.

The potential issue will also arise whenever the importer and the
imported modules have different semantics on release(). If C attempts to
shutdown itself when release() is called, while B simply treats it as a
no-op, it is possible that B might still attempt to access C afterwards
because B might have no knowledge of what C is doing internally. We'll
need to document this so developers will be aware of the issues.

Yep.

- Stanley

Reply via email to