--- perl-current/ext/threads/shared/shared.xs
+++ perl-current/ext/threads/shared/shared.xs
@@ -1340,6 +1340,20 @@
 
 
 void
+_is_destroyable(SV *shared_var)
+    PROTOTYPE: \[$@%]
+    PREINIT:
+        SV *ssv;
+    CODE:
+        shared_var = SvRV(shared_var);
+        if (SvROK(shared_var))
+            shared_var = SvRV(shared_var);
+        ssv = Perl_sharedsv_find(aTHX_ shared_var);
+        ST(0) = (ssv && (SvREFCNT(ssv) > 1)) ? &PL_sv_no : &PL_sv_yes;
+        /* XSRETURN(1); - implied */
+
+
+void
 share(SV *myref)
     PROTOTYPE: \[$@%]
     CODE:

--- perl-current/sv.c
+++ perl-current/sv.c
@@ -5099,45 +5099,70 @@
 
     if (SvOBJECT(sv)) {
 	if (PL_defstash) {		/* Still have a symbol table? */
-	    dSP;
-	    HV* stash;
-	    do {	
-		CV* destructor;
-		stash = SvSTASH(sv);
-		destructor = StashHANDLER(stash,DESTROY);
-		if (destructor) {
-		    SV* const tmpref = newRV(sv);
-	            SvREADONLY_on(tmpref);   /* DESTROY() could be naughty */
-		    ENTER;
-		    PUSHSTACKi(PERLSI_DESTROY);
-		    EXTEND(SP, 2);
-		    PUSHMARK(SP);
-		    PUSHs(tmpref);
-		    PUTBACK;
-		    call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
-		
-		
-		    POPSTACK;
-		    SPAGAIN;
-		    LEAVE;
-		    if(SvREFCNT(tmpref) < 2) {
-		        /* tmpref is not kept alive! */
-		        SvREFCNT(sv)--;
-			SvRV_set(tmpref, NULL);
-			SvROK_off(tmpref);
-		    }
-		    SvREFCNT_dec(tmpref);
-		}
-	    } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
+#ifdef USE_ITHREADS
+	    IV destroyable;
+	    CV *check_destroyable = get_cv("threads::shared::_is_destroyable", 0);
+	    if (check_destroyable) {
+		dSP;
+		int count;
+		ENTER;
+		SAVETMPS;
+		PUSHMARK(SP);
+		XPUSHs(sv);
+		PUTBACK;
+		count = call_sv((SV*)check_destroyable, G_SCALAR);
+		SPAGAIN;
+		if (count != 1)
+		    Perl_croak(aTHX_ "'threads::shared::_is_destroyable' failed to return result");
+		destroyable = POPi;
+		PUTBACK;
+		FREETMPS;
+		LEAVE;
+	    } else {
+		destroyable = 1;
+	    }
 
+	    if (destroyable) {
+#endif
+		HV* stash;
+		do {
+		    dSP;
+		    CV* destructor;
+		    stash = SvSTASH(sv);
+		    destructor = StashHANDLER(stash,DESTROY);
+		    if (destructor) {
+			SV* const tmpref = newRV(sv);
+			SvREADONLY_on(tmpref);   /* DESTROY() could be naughty */
+			ENTER;
+			PUSHSTACKi(PERLSI_DESTROY);
+			EXTEND(SP, 2);
+			PUSHMARK(SP);
+			PUSHs(tmpref);
+			PUTBACK;
+			call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
+			POPSTACK;
+			SPAGAIN;
+			LEAVE;
+			if(SvREFCNT(tmpref) < 2) {
+			    /* tmpref is not kept alive! */
+			    SvREFCNT(sv)--;
+			    SvRV_set(tmpref, NULL);
+			    SvROK_off(tmpref);
+			}
+			SvREFCNT_dec(tmpref);
+		    }
+		} while (SvOBJECT(sv) && SvSTASH(sv) != stash);
 
-	    if (SvREFCNT(sv)) {
-		if (PL_in_clean_objs)
-		    Perl_croak(aTHX_ "DESTROY created new reference to dead object '%s'",
-			  HvNAME_get(stash));
-		/* DESTROY gave object new lease on life */
-		return;
+		if (SvREFCNT(sv)) {
+		    if (PL_in_clean_objs)
+			Perl_croak(aTHX_ "DESTROY created new reference to dead object '%s'",
+			      HvNAME_get(stash));
+		    /* DESTROY gave object new lease on life */
+		    return;
+		}
+#ifdef USE_ITHREADS
 	    }
+#endif
 	}
 
 	if (SvOBJECT(sv)) {
