On Aug 2, 2014, at 20:24 , Marvin Humphrey <[email protected]> wrote:
> Agreed about mutability being OK during initalization, but what I'm referring
> to are member variables:
>
> * Clownfish::Class => "name" (String)
> * Clownfish::Class => "methods" (VArray)
> * Clownfish::Method => "name" (String)
> * Clownfish::Method => "host_alias" (String)
>
> Under refcounting hosts, the refcounts of all of those objects are vulnerable
> to race bugs under multi-threading.
>
> Under Perl we also have the cached host object to think about; that won't be a
> concern under e.g. Python because Clownfish objects will inherit from Python's
> `object` rather than cache a host object. Perl is probably an odd case here.
>
> Since the refcounts on Class and Method objects are held constant, they are
> not themselves vulnerable to refcount race conditions -- but that's not true
> for member variables whose refcounts are not held constant.
Ah, the refcounts.
> In addition, the "methods" VArray is a concern because unlike the Strings, its
> content is mutable.
>
> I think the most straightforward way to address this issue would be to use
> raw arrays instead of Clownfish types, with `char*` in place of String
> and `Method**` in place of the VArray. That would be annoying, though,
> for frequently accessed members like `name`.
>
> Perhaps a better option would be to control refcounting with a flag.
>
> if (!(obj->ref.count & CFISH_OBJ_IS_IMMORTAL)) {
> ...
> }
This would also mean that “immortal” Perl host objects must be SvSHAREd, right?
Otherwise, manipulating the Perl refcount wouldn’t be thread-safe.
> If we do that, then we don't need refcounting to go through method calls any
> more. The only reason we've ever needed to override the refcounting methods
> is to thwart refcounting (Class, Method, HashTombStone, RawPosting).
Another approach is to clone the class registry for every Perl thread.
Something like that should work:
- Store the class registry in a Perl global. This would mean we need a
host-specific function to fetch the registry.
- Define the special CLONE method which is invoked whenever Perl creates
a new thread. This method would clone the registry and store it in the
new thread’s version of the global variable.
Then we wouldn’t have to care about thread-safety of refcount handling at all.
Nick