From: Captain Obvious on
JCB> Also, make-instance and its "two step"
JCB> process feels like a source of troubles.
JCB> First call generic-function "allocate-instance"
JCB> and then call generic-function "initialize-instance";
JCB> what about the void between these two?
JCB> I would hate to have to grab a lock to
JCB> instantiate objects!

Then maybe it is better solved on application level?

During development you probably do not need to care.
If you want to hot-patch thing in production you might want to make
something like read-write lock.

E.g. if your application is serving requests it grabs "code read" lock for
duration of request.
When you want to hotpatch you grab "code write" lock and after all request
release read locks you can hotpatch code.
Then new requests will use new code.

Probably this is the only way to guarantee consitency for hotpatching. (It's
not like I'm an expert in this, just speculating.)

You cannot guarantee this sort of consistency on implementation level, so
why try at all?
From practical perspecitves attempt to do that would be half-assed, but
still might impose some overhead, as you've noted above.

So I think instead of making it abstractly safe it is better to make it
documented and reasonable -- bad things which can happen should be
documented and unreasonably bad things should be fixed.

From: Tim Bradshaw on
On 2010-08-11 15:46:51 +0100, Jean-Claude Beaudoin said:

> The first one is in the event of a change in the DAG of classes that
> happen to modify the class precedence list (CPL) of a class for which a
> make-instance is in progress. I don't have much hope for the coherence
> of the whole set of allocate-instance, instance-initialize and
> shared-initialize if they have been customized with code that share
> some critical assumptions about the class they work on.

I'm with Kenny: find the people who write code which has this problem,
kill them and sell them for pet food.

From: Günther Thomsen on
On Aug 11, 7:46 am, Jean-Claude Beaudoin
<jean.claude.beaud...(a)gmail.com> wrote:
> I missed the fact that there is a third generic function involved in the business of make-instance: shared-initialize.
> So it makes for at least two (if not three) holes through which trouble can creep in. First between allocate-instance
> and instance-initialize and second between the beginning of instance-initialize and its own invocation of shared-initialize.
>
Two/three holes? This assumes that allocate-instance, instance-
initialize, etc. are atomic operations, doesn't it? Please ignore my
ignorance, but are they specified to be that way? Are they implemented
that way?
From: Jean-Claude Beaudoin on
Tim Bradshaw wrote:
> On 2010-08-11 15:46:51 +0100, Jean-Claude Beaudoin said:
>
>> The first one is in the event of a change in the DAG of classes that
>> happen to modify the class precedence list (CPL) of a class for which
>> a make-instance is in progress. I don't have much hope for the
>> coherence of the whole set of allocate-instance, instance-initialize
>> and shared-initialize if they have been customized with code that
>> share some critical assumptions about the class they work on.
>
> I'm with Kenny: find the people who write code which has this problem,
> kill them and sell them for pet food.
>

Well, in CLOS, class redefinition is an advertised feature supported by an officially standard protocol
(update-instance-for-???-class, make-instances-obsolete). Considering that, the scenario I mentioned is not far-fetched
and is not an abuse of the system. So I think that the issue here cannot be dismissed trivially.

From: Jean-Claude Beaudoin on
G�nther Thomsen wrote:
> On Aug 11, 7:46 am, Jean-Claude Beaudoin
> <jean.claude.beaud...(a)gmail.com> wrote:
>> I missed the fact that there is a third generic function involved in the business of make-instance: shared-initialize.
>> So it makes for at least two (if not three) holes through which trouble can creep in. First between allocate-instance
>> and instance-initialize and second between the beginning of instance-initialize and its own invocation of shared-initialize.
>>
> Two/three holes? This assumes that allocate-instance, instance-
> initialize, etc. are atomic operations, doesn't it? Please ignore my
> ignorance, but are they specified to be that way? Are they implemented
> that way?

Yes, in that statement I did assume the mentioned generic functions to be "atomic with respect to CLOS metadata" which
is a kind of worst case against the point I was trying to make in an informal way which is: there exists a lower bound,
that is not zero, on the number of regions, that I called holes, where synchronization issues can appear. If you remove
that "atomicity" assumption the situation only gets even worst.

The ANSI CL standard is silent on any aspect involving multi-threading including this one. But usually the business of
generic functions with respect to CLOS metadata is done by a call to compute-applicable-methods followed by a call to
compute-effective-method, both MOP generic functions. The result of this is usually cached somewhere and is reused in
subsequent calls to the generic function, thus it gives somewhat of an "atomic" flavor to the thing. One would also
wish very strongly that the sequence compute-applicable-methods+compute-effective-method be atomic with respect to CLOS
metadata mutation but nothing in the standard on that.

There is currently some locking done in the CLOS code of SBCL but one gets the impression from reading the code that
this was done more as a partial treatment of an immediate symptom (crash following redefinition of a class) than as a
cure for the disease.