perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stas Bekman <s...@stason.org>
Subject Re: [mp2] Our API is not perl thread-safe
Date Thu, 24 Mar 2005 23:06:12 GMT
Stas Bekman wrote:
> Stas Bekman wrote:
> [...]
> 
>> First of all we have to separate the objects in two groups: those 
>> created by users (1) and those created by Apache/mp2 (2).
>>
>> (1) things which are completely under user control look easy, for 
>> example if you create an APR::Table object, we can clone it by copying 
>> the table in the spawned thread. The question is what pool should we 
>> use for that purpose? We can't use the pool from the parent thread. 
>> Since the parent thread may be killed before the child one (for 
>> detached threads). and if it's APR::Pool object itself that needs to 
>> be cloned, which pool do we use to clone it? How do we avoid leaks?
>>
>> Ideas? I'm not sure it's doable at all.
>>
>> (2) Things are even harder with objects created by Apache/mp2. I mean 
>> how in the world are we going to clone things like $r or $c? there are 
>> all kind of things attached to those objects, including sockets, etc. 
>> and now we suddenly need to free those objects too.
>>
>> Here I'm even more lost.
> 
> 
> I think I've an idea that may work. All that automatic cloning business 
> is really unwanted in the mod_perl environment. I think if we try to 
> empty the cloned objects of the pointer to the C struct, it will render 
> them unusable in the spawned threads, but it'll prevent multiple 
> destruction problem. Next we can try and see if we can properly clone 
> objects, one class at a time.
> 
> Unfortunately due to the badly-designed by the perl core CLONE function 
> it's going to be quite a hassle to do even that, as you can see from 
> Example::CLONE. :(
> 
> I'll try with APR::Pool first.
> 
> Stas, who enjoys talking to himself...

The following seems to make APR::Pool objects "happy" (=nosegfault) under 
ithread cloning. But it's going to be a pain to do that for each class, 
since there are more than one entry point. I wish CLONE was implemented 
differently. Luckily I didn't have to use Scalar::Util, so the code is a 
bit simpler.

Index: xs/APR/Pool/APR__Pool.h
===================================================================
--- xs/APR/Pool/APR__Pool.h	(revision 158003)
+++ xs/APR/Pool/APR__Pool.h	(working copy)
@@ -216,6 +216,22 @@
          if (parent_pool) {
              mpxs_add_pool_magic(rv, parent_pool_obj);
          }
+
+        {
+            HV *hv;
+            SV *weak_rv, *sv_key;
+
+            /* $objects{"$$self"} = $self;
+               Scalar::Util::weaken($objects{"$$self"})
+            */
+            hv = get_hv("APR::Pool::CLONE_objects", TRUE);
+            /* use the real object pointer as a unique key */
+            sv_key = newSVpvf("%p", SvIVX(SvRV(rv)));
+            weak_rv = newRV(SvRV(rv));
+            sv_rvweaken(weak_rv); /* ala Scalar::Util::weaken */
+            hv_store_ent(hv, sv_key, weak_rv, FALSE);
+            sv_free(sv_key);
+        }

          return rv;
      }
@@ -369,8 +385,32 @@
      SV *sv = SvRV(obj);

      if (MP_APR_POOL_SV_HAS_OWNERSHIP(sv)) {
+        HV *hv = get_hv("APR::Pool::CLONE_objects", TRUE);
+        SV *sv_key = newSVpvf("%p", SvIVX(SvRV(obj)));
+        /* delete $CLONE_objects{"$$self"}; */
+        hv_delete_ent(hv, sv_key, G_DISCARD, FALSE);
+        sv_free(sv_key);
+
          apr_pool_t *p = mpxs_sv_object_deref(obj, apr_pool_t);
          apr_pool_destroy(p);
      }
  }

+static void make_hollow(pTHX_ SV *obj)
+{
+    SV *sv = SvRV(obj);
+    /* detach form the C struct and invalidate */
+    SvIVX(sv) = 0;
+    SvIOK_off(sv);
+    mg_free(sv); /* remove any magic */
+}
+
+static MP_INLINE void mpxs_apr_pool_CLONE(pTHX_ SV *class)
+{
+    HE *he;
+    HV *hv = get_hv("APR::Pool::CLONE_objects", TRUE);
+    hv_iterinit(hv);
+    while ((he = hv_iternext(hv))) {
+        make_hollow(aTHX_ hv_iterval(hv, he));
+    }
+}

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Mime
View raw message