On Tue, Aug 5, 2014 at 2:50 AM, Nick Wellnhofer <[email protected]> wrote:
> On 04/08/2014 22:37, Marvin Humphrey wrote:

>> Could we instead decide that Clone() is not thread safe?  And then in the
>> context of duplicating `klass->name` and the like we'd use some other
>> constructor instead of Clone().
>
> OK with me. It will only be surprising for anyone who really needs to clone
> a String and doesn't know that String is special in that regard.

Yeah, you're right. :\

We have a funny overlap between Clone() and Inc_RefCount().  Both involve
taking ownership of a refcount.  Both involve optimizations around
not-completely independent copies.

I feel like we ought to be able to disentangle this situation, and that when
we finish there should be fewer methods on Obj.  The best answer will probably
reveal itself as we add more host languages.

> It depends on what guarantees LFReg#Clone should make exactly. I think it's
> OK if it returns a clone of the registry in some arbitrary state during the
> cloning process. For example, if a single object is inserted during the
> cloning process, it would be OK to return a clone without that object. The
> registry could change immediately after the final size check anyway.
>
> But my implementation could return a version of the registry in a completely
> different state. If, during cloning, object A is inserted first and then
> object B, a version with only object B could be returned. This is clearly a
> bug, so let's skip that commit.
>
>> Iteration, in contrast, simply cannot defend against concurrent
>> modifications without locking.  And therefore this implementation suffices.
>> Very nice, actually!
>
> Iteration suffers from the same problem mentioned above. This could, for
> example, lead to finding a class but not its parent.
>
> This is all more complicated than I initially thought, so I'll leave LFReg
> as is.

Check out the caveats in the docs on iteration with Java's ConcurrentHashMap
or enumeration with C#'s ConcurrentDictionary.  It doesn't matter what kind of
engineering resources you throw at this problem -- even exemplary
implementations are incredibly hard to reason about and use safely.

"All shared state immutable and all mutable state thread-private" ought to be
an acceptable model of concurrency for Clownfish.  Abstracting a common
interface which generalizes the wildly varying multi-threading capabilities of
various hosts is not feasible in any case.

I'm content to have LockFreeRegistry remain a private implementation detail of
the Clownfish runtime forever -- exposing it as a public API is not central to
the project's mission.

>> One thing to think about is that if we add interfaces to Clownfish, we'll
>> have to normalize the various signatures of Next(), perhaps necessitating
>> that we access key and value via Get_Key() and Get_Value().  But that
>> applies to several other iterators as well, so shouldn't block this commit.
>
> +1 for Get_Key() and Get_Value(). I'm also for separate Iterator objects in
> general. But let's ignore that for now.

The iterator you wrote for LockFreeRegistry could easily be adapted for Hash.
I talked to my colleague Tim Wilkens about that today and it looks like he's
interested in picking up that task.

Marvin Humphrey

Reply via email to