threads::shared 1.06
[p5sagit/p5-mst-13.2.git] / ext / threads / shared / shared.xs
1 /*    shared.xs
2  *
3  *    Copyright (c) 2001-2002, 2006 Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  * "Hand any two wizards a piece of rope and they would instinctively pull in
9  * opposite directions."
10  *                         --Sourcery
11  *
12  * Contributed by Artur Bergman <sky AT crucially DOT net>
13  * Pulled in the (an)other direction by Nick Ing-Simmons
14  *      <nick AT ing-simmons DOT net>
15  * CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>
16  */
17
18 /*
19  * Shared variables are implemented by a scheme similar to tieing.
20  * Each thread has a proxy SV with attached magic -- "private SVs" --
21  * which all point to a single SV in a separate shared interpreter
22  * (PL_sharedsv_space) -- "shared SVs".
23  *
24  * The shared SV holds the variable's true values, and its state is
25  * copied between the shared and private SVs with the usual
26  * mg_get()/mg_set() arrangement.
27  *
28  * Aggregates (AVs and HVs) are implemented using tie magic, except that
29  * the vtable used is one defined in this file rather than the standard one.
30  * This means that where a tie function like FETCH is normally invoked by
31  * the tie magic's mg_get() function, we completely bypass the calling of a
32  * perl-level function, and directly call C-level code to handle it. On
33  * the other hand, calls to functions like PUSH are done directly by code
34  * in av.c, etc., which we can't bypass. So the best we can do is to provide
35  * XS versions of these functions. We also have to attach a tie object,
36  * blessed into the class threads::shared::tie, to keep the method-calling
37  * code happy.
38  *
39  * Access to aggregate elements is done the usual tied way by returning a
40  * proxy PVLV element with attached element magic.
41  *
42  * Pointers to the shared SV are squirrelled away in the mg->mg_ptr field
43  * of magic (with mg_len == 0), and in the IV2PTR(SvIV(sv)) field of tied
44  * object SVs. These pointers have to be hidden like this because they
45  * cross interpreter boundaries, and we don't want sv_clear() and friends
46  * following them.
47  *
48  * The three basic shared types look like the following:
49  *
50  * -----------------
51  *
52  * Shared scalar (my $s : shared):
53  *
54  *  SV = PVMG(0x7ba238) at 0x7387a8
55  *   FLAGS = (PADMY,GMG,SMG)
56  *   MAGIC = 0x824d88
57  *     MG_TYPE = PERL_MAGIC_shared_scalar(n)
58  *     MG_PTR = 0x810358                <<<< pointer to the shared SV
59  *
60  * -----------------
61  *
62  * Shared aggregate (my @a : shared;  my %h : shared):
63  *
64  * SV = PVAV(0x7175d0) at 0x738708
65  *   FLAGS = (PADMY,RMG)
66  *   MAGIC = 0x824e48
67  *     MG_TYPE = PERL_MAGIC_tied(P)
68  *     MG_OBJ = 0x7136e0                <<<< ref to the tied object
69  *     SV = RV(0x7136f0) at 0x7136e0
70  *       RV = 0x738640
71  *       SV = PVMG(0x7ba238) at 0x738640 <<<< the tied object
72  *         FLAGS = (OBJECT,IOK,pIOK)
73  *         IV = 8455000                 <<<< pointer to the shared AV
74  *         STASH = 0x80abf0 "threads::shared::tie"
75  *     MG_PTR = 0x810358 ""             <<<< another pointer to the shared AV
76  *   ARRAY = 0x0
77  *
78  * -----------------
79  *
80  * Aggregate element (my @a : shared; $a[0])
81  *
82  * SV = PVLV(0x77f628) at 0x713550
83  *   FLAGS = (GMG,SMG,RMG,pIOK)
84  *   MAGIC = 0x72bd58
85  *     MG_TYPE = PERL_MAGIC_shared_scalar(n)
86  *     MG_PTR = 0x8103c0 ""             <<<< pointer to the shared element
87  *   MAGIC = 0x72bd18
88  *     MG_TYPE = PERL_MAGIC_tiedelem(p)
89  *     MG_OBJ = 0x7136e0                <<<< ref to the tied object
90  *     SV = RV(0x7136f0) at 0x7136e0
91  *       RV = 0x738660
92  *       SV = PVMG(0x7ba278) at 0x738660 <<<< the tied object
93  *         FLAGS = (OBJECT,IOK,pIOK)
94  *         IV = 8455064                 <<<< pointer to the shared AV
95  *         STASH = 0x80ac30 "threads::shared::tie"
96  *   TYPE = t
97  *
98  * Note that PERL_MAGIC_tiedelem(p) magic doesn't have a pointer to a
99  * shared SV in mg_ptr; instead this is used to store the hash key,
100  * if any, like normal tied elements. Note also that element SVs may have
101  * pointers to both the shared aggregate and the shared element.
102  *
103  *
104  * Userland locks:
105  *
106  * If a shared variable is used as a perl-level lock or condition
107  * variable, then PERL_MAGIC_ext magic is attached to the associated
108  * *shared* SV, whose mg_ptr field points to a malloc'ed structure
109  * containing the necessary mutexes and condition variables.
110  *
111  * Nomenclature:
112  *
113  * In this file, any variable name prefixed with 's' (e.g., ssv, stmp or sobj)
114  * usually represents a shared SV which corresponds to a private SV named
115  * without the prefix (e.g., sv, tmp or obj).
116  */
117
118 /* Patch status:
119  *
120  * Perl 5.8.8 contains threads::shared patches up to 26626 (equivalent to
121  * blead patches 26350+26351).
122  *
123  * The CPAN version of threads::shared contains the following blead patches:
124  *      26569 (applicable to 5.9.3 only)
125  *      26684
126  *      26693
127  *      26695
128  */
129
130 #define PERL_NO_GET_CONTEXT
131 #include "EXTERN.h"
132 #include "perl.h"
133 #include "XSUB.h"
134 #ifdef HAS_PPPORT_H
135 #define NEED_vnewSVpvf
136 #define NEED_warner
137 #  include "ppport.h"
138 #  include "shared.h"
139 #endif
140
141 #ifdef USE_ITHREADS
142
143 /*
144  * The shared things need an intepreter to live in ...
145  */
146 PerlInterpreter *PL_sharedsv_space;             /* The shared sv space */
147 /* To access shared space we fake aTHX in this scope and thread's context */
148
149 /* Bug #24255: We include ENTER+SAVETMPS/FREETMPS+LEAVE with
150  * SHARED_CONTEXT/CALLER_CONTEXT macros, so that any mortals, etc. created
151  * while in the shared interpreter context don't languish */
152
153 #define SHARED_CONTEXT                                  \
154     STMT_START {                                        \
155         PERL_SET_CONTEXT((aTHX = PL_sharedsv_space));   \
156         ENTER;                                          \
157         SAVETMPS;                                       \
158     } STMT_END
159
160 /* So we need a way to switch back to the caller's context... */
161 /* So we declare _another_ copy of the aTHX variable ... */
162 #define dTHXc PerlInterpreter *caller_perl = aTHX
163
164 /* ... and use it to switch back */
165 #define CALLER_CONTEXT                                  \
166     STMT_START {                                        \
167         FREETMPS;                                       \
168         LEAVE;                                          \
169         PERL_SET_CONTEXT((aTHX = caller_perl));         \
170     } STMT_END
171
172 /*
173  * Only one thread at a time is allowed to mess with shared space.
174  */
175
176 typedef struct {
177     perl_mutex          mutex;
178     PerlInterpreter    *owner;
179     I32                 locks;
180     perl_cond           cond;
181 #ifdef DEBUG_LOCKS
182     char *              file;
183     int                 line;
184 #endif
185 } recursive_lock_t;
186
187 recursive_lock_t PL_sharedsv_lock;   /* Mutex protecting the shared sv space */
188
189 void
190 recursive_lock_init(pTHX_ recursive_lock_t *lock)
191 {
192     Zero(lock,1,recursive_lock_t);
193     MUTEX_INIT(&lock->mutex);
194     COND_INIT(&lock->cond);
195 }
196
197 void
198 recursive_lock_destroy(pTHX_ recursive_lock_t *lock)
199 {
200     MUTEX_DESTROY(&lock->mutex);
201     COND_DESTROY(&lock->cond);
202 }
203
204 void
205 recursive_lock_release(pTHX_ recursive_lock_t *lock)
206 {
207     MUTEX_LOCK(&lock->mutex);
208     if (lock->owner == aTHX) {
209         if (--lock->locks == 0) {
210             lock->owner = NULL;
211             COND_SIGNAL(&lock->cond);
212         }
213     }
214     MUTEX_UNLOCK(&lock->mutex);
215 }
216
217 void
218 recursive_lock_acquire(pTHX_ recursive_lock_t *lock, char *file, int line)
219 {
220     assert(aTHX);
221     MUTEX_LOCK(&lock->mutex);
222     if (lock->owner == aTHX) {
223         lock->locks++;
224     } else {
225         while (lock->owner) {
226 #ifdef DEBUG_LOCKS
227             Perl_warn(aTHX_ " %p waiting - owned by %p %s:%d\n",
228                       aTHX, lock->owner, lock->file, lock->line);
229 #endif
230             COND_WAIT(&lock->cond,&lock->mutex);
231         }
232         lock->locks = 1;
233         lock->owner = aTHX;
234 #ifdef DEBUG_LOCKS
235         lock->file  = file;
236         lock->line  = line;
237 #endif
238     }
239     MUTEX_UNLOCK(&lock->mutex);
240     SAVEDESTRUCTOR_X(recursive_lock_release,lock);
241 }
242
243 #define ENTER_LOCK                                                          \
244     STMT_START {                                                            \
245         ENTER;                                                              \
246         recursive_lock_acquire(aTHX_ &PL_sharedsv_lock, __FILE__, __LINE__);\
247     } STMT_END
248
249 /* The unlocking is done automatically at scope exit */
250 #define LEAVE_LOCK      LEAVE
251
252
253 /* A common idiom is to acquire access and switch in ... */
254 #define SHARED_EDIT     \
255     STMT_START {        \
256         ENTER_LOCK;     \
257         SHARED_CONTEXT; \
258     } STMT_END
259
260 /* ... then switch out and release access. */
261 #define SHARED_RELEASE  \
262     STMT_START {        \
263         CALLER_CONTEXT; \
264         LEAVE_LOCK;     \
265     } STMT_END
266
267
268 /* User-level locks:
269    This structure is attached (using ext magic) to any shared SV that
270    is used by user-level locking or condition code
271 */
272
273 typedef struct {
274     recursive_lock_t    lock;           /* For user-levl locks */
275     perl_cond           user_cond;      /* For user-level conditions */
276 } user_lock;
277
278 /* Magic used for attaching user_lock structs to shared SVs
279
280    The vtable used has just one entry - when the SV goes away
281    we free the memory for the above.
282  */
283
284 int
285 sharedsv_userlock_free(pTHX_ SV *sv, MAGIC *mg)
286 {
287     user_lock *ul = (user_lock *) mg->mg_ptr;
288     assert(aTHX == PL_sharedsv_space);
289     if (ul) {
290         recursive_lock_destroy(aTHX_ &ul->lock);
291         COND_DESTROY(&ul->user_cond);
292         PerlMemShared_free(ul);
293         mg->mg_ptr = NULL;
294     }
295     return (0);
296 }
297
298 MGVTBL sharedsv_userlock_vtbl = {
299     0,                          /* get */
300     0,                          /* set */
301     0,                          /* len */
302     0,                          /* clear */
303     sharedsv_userlock_free,     /* free */
304     0,                          /* copy */
305     0,                          /* dup */
306 #ifdef MGf_LOCAL
307     0,                          /* local */
308 #endif
309 };
310
311 /*
312  * Access to shared things is heavily based on MAGIC
313  *      - in mg.h/mg.c/sv.c sense
314  */
315
316 /* In any thread that has access to a shared thing there is a "proxy"
317    for it in its own space which has 'MAGIC' associated which accesses
318    the shared thing.
319  */
320
321 extern MGVTBL sharedsv_scalar_vtbl;    /* Scalars have this vtable */
322 extern MGVTBL sharedsv_array_vtbl;     /* Hashes and arrays have this
323                                             - like 'tie' */
324 extern MGVTBL sharedsv_elem_vtbl;      /* Elements of hashes and arrays have
325                                           this _AS WELL AS_ the scalar magic:
326    The sharedsv_elem_vtbl associates the element with the array/hash and
327    the sharedsv_scalar_vtbl associates it with the value
328  */
329
330
331 /* Get shared aggregate SV pointed to by threads::shared::tie magic object */
332
333 STATIC SV *
334 S_sharedsv_from_obj(pTHX_ SV *sv)
335 {
336      return ((SvROK(sv)) ? INT2PTR(SV *, SvIV(SvRV(sv))) : NULL);
337 }
338
339
340 /* Return the user_lock structure (if any) associated with a shared SV.
341  * If create is true, create one if it doesn't exist
342  */
343 STATIC user_lock *
344 S_get_userlock(pTHX_ SV* ssv, bool create)
345 {
346     MAGIC *mg;
347     user_lock *ul = NULL;
348
349     assert(ssv);
350     /* XXX Redesign the storage of user locks so we don't need a global
351      * lock to access them ???? DAPM */
352     ENTER_LOCK;
353     mg = mg_find(ssv, PERL_MAGIC_ext);
354     if (mg) {
355         ul = (user_lock*)(mg->mg_ptr);
356     } else if (create) {
357         dTHXc;
358         SHARED_CONTEXT;
359         ul = (user_lock *) PerlMemShared_malloc(sizeof(user_lock));
360         Zero(ul, 1, user_lock);
361         /* Attach to shared SV using ext magic */
362         sv_magicext(ssv, NULL, PERL_MAGIC_ext, &sharedsv_userlock_vtbl,
363                (char *)ul, 0);
364         recursive_lock_init(aTHX_ &ul->lock);
365         COND_INIT(&ul->user_cond);
366         CALLER_CONTEXT;
367     }
368     LEAVE_LOCK;
369     return (ul);
370 }
371
372
373 /* Given a private side SV tries to find if the SV has a shared backend,
374  * by looking for the magic.
375  */
376 SV *
377 Perl_sharedsv_find(pTHX_ SV *sv)
378 {
379     MAGIC *mg;
380     if (SvTYPE(sv) >= SVt_PVMG) {
381         switch(SvTYPE(sv)) {
382         case SVt_PVAV:
383         case SVt_PVHV:
384             if ((mg = mg_find(sv, PERL_MAGIC_tied))
385                 && mg->mg_virtual == &sharedsv_array_vtbl) {
386                 return ((SV *)mg->mg_ptr);
387             }
388             break;
389         default:
390             /* This should work for elements as well as they
391              * have scalar magic as well as their element magic
392              */
393             if ((mg = mg_find(sv, PERL_MAGIC_shared_scalar))
394                 && mg->mg_virtual == &sharedsv_scalar_vtbl) {
395                 return ((SV *)mg->mg_ptr);
396             }
397             break;
398         }
399     }
400     /* Just for tidyness of API also handle tie objects */
401     if (SvROK(sv) && sv_derived_from(sv, "threads::shared::tie")) {
402         return (S_sharedsv_from_obj(aTHX_ sv));
403     }
404     return (NULL);
405 }
406
407
408 /* Associate a private SV  with a shared SV by pointing the appropriate
409  * magics at it.
410  * Assumes lock is held.
411  */
412 void
413 Perl_sharedsv_associate(pTHX_ SV *sv, SV *ssv)
414 {
415     dTHXc;
416     MAGIC *mg = 0;
417
418     /* If we are asked for any private ops we need a thread */
419     assert ( aTHX !=  PL_sharedsv_space );
420
421     /* To avoid need for recursive locks require caller to hold lock */
422     assert ( PL_sharedsv_lock.owner == aTHX );
423
424     switch(SvTYPE(sv)) {
425     case SVt_PVAV:
426     case SVt_PVHV:
427         if (!(mg = mg_find(sv, PERL_MAGIC_tied))
428             || mg->mg_virtual != &sharedsv_array_vtbl
429             || (SV*) mg->mg_ptr != ssv)
430         {
431             SV *obj = newSV(0);
432             sv_setref_iv(obj, "threads::shared::tie", PTR2IV(ssv));
433             if (mg) {
434                 sv_unmagic(sv, PERL_MAGIC_tied);
435             }
436             mg = sv_magicext(sv, obj, PERL_MAGIC_tied, &sharedsv_array_vtbl,
437                             (char *)ssv, 0);
438             mg->mg_flags |= (MGf_COPY|MGf_DUP);
439             SvREFCNT_inc_void(ssv);
440             SvREFCNT_dec(obj);
441         }
442         break;
443
444     default:
445         if ((SvTYPE(sv) < SVt_PVMG)
446             || !(mg = mg_find(sv, PERL_MAGIC_shared_scalar))
447             || mg->mg_virtual != &sharedsv_scalar_vtbl
448             || (SV*) mg->mg_ptr != ssv)
449         {
450             if (mg) {
451                 sv_unmagic(sv, PERL_MAGIC_shared_scalar);
452             }
453             mg = sv_magicext(sv, Nullsv, PERL_MAGIC_shared_scalar,
454                             &sharedsv_scalar_vtbl, (char *)ssv, 0);
455             mg->mg_flags |= (MGf_DUP
456 #ifdef MGf_LOCAL
457                                     |MGf_LOCAL
458 #endif
459                             );
460             SvREFCNT_inc_void(ssv);
461         }
462         break;
463     }
464
465     assert ( Perl_sharedsv_find(aTHX_ sv) == ssv );
466 }
467
468
469 /* Given a private SV, create and return an associated shared SV.
470  * Assumes lock is held.
471  */
472 STATIC SV *
473 S_sharedsv_new_shared(pTHX_ SV *sv)
474 {
475     dTHXc;
476     SV *ssv;
477
478     assert(PL_sharedsv_lock.owner == aTHX);
479     assert(aTHX !=  PL_sharedsv_space);
480
481     SHARED_CONTEXT;
482     ssv = newSV(0);
483     SvREFCNT(ssv) = 0; /* Will be upped to 1 by Perl_sharedsv_associate */
484     sv_upgrade(ssv, SvTYPE(sv));
485     CALLER_CONTEXT;
486     Perl_sharedsv_associate(aTHX_ sv, ssv);
487     return (ssv);
488 }
489
490
491 /* Given a shared SV, create and return an associated private SV.
492  * Assumes lock is held.
493  */
494 STATIC SV *
495 S_sharedsv_new_private(pTHX_ SV *ssv)
496 {
497     SV *sv;
498
499     assert(PL_sharedsv_lock.owner == aTHX);
500     assert(aTHX !=  PL_sharedsv_space);
501
502     sv = newSV(0);
503     sv_upgrade(sv, SvTYPE(ssv));
504     Perl_sharedsv_associate(aTHX_ sv, ssv);
505     return (sv);
506 }
507
508
509 /* A threadsafe version of SvREFCNT_dec(ssv) */
510
511 STATIC void
512 S_sharedsv_dec(pTHX_ SV* ssv)
513 {
514     if (! ssv)
515         return;
516     ENTER_LOCK;
517     if (SvREFCNT(ssv) > 1) {
518         /* No side effects, so can do it lightweight */
519         SvREFCNT_dec(ssv);
520     } else {
521         dTHXc;
522         SHARED_CONTEXT;
523         SvREFCNT_dec(ssv);
524         CALLER_CONTEXT;
525     }
526     LEAVE_LOCK;
527 }
528
529
530 /* Implements Perl-level share() and :shared */
531
532 void
533 Perl_sharedsv_share(pTHX_ SV *sv)
534 {
535     switch(SvTYPE(sv)) {
536     case SVt_PVGV:
537         Perl_croak(aTHX_ "Cannot share globs yet");
538         break;
539
540     case SVt_PVCV:
541         Perl_croak(aTHX_ "Cannot share subs yet");
542         break;
543
544     default:
545         ENTER_LOCK;
546         (void) S_sharedsv_new_shared(aTHX_ sv);
547         LEAVE_LOCK;
548         SvSETMAGIC(sv);
549         break;
550     }
551 }
552
553
554 #if defined(WIN32) || defined(OS2)
555 #  define ABS2RELMILLI(abs)             \
556     do {                                \
557         abs -= (double)time(NULL);      \
558         if (abs > 0) { abs *= 1000; }   \
559         else         { abs  = 0;    }   \
560     } while (0)
561 #endif /* WIN32 || OS2 */
562
563 /* Do OS-specific condition timed wait */
564
565 bool
566 Perl_sharedsv_cond_timedwait(perl_cond *cond, perl_mutex *mut, double abs)
567 {
568 #if defined(NETWARE) || defined(FAKE_THREADS) || defined(I_MACH_CTHREADS)
569     Perl_croak_nocontext("cond_timedwait not supported on this platform");
570 #else
571 #  ifdef WIN32
572     int got_it = 0;
573
574     ABS2RELMILLI(abs);
575
576     cond->waiters++;
577     MUTEX_UNLOCK(mut);
578     /* See comments in win32/win32thread.h COND_WAIT vis-a-vis race */
579     switch (WaitForSingleObject(cond->sem, (DWORD)abs)) {
580         case WAIT_OBJECT_0:   got_it = 1; break;
581         case WAIT_TIMEOUT:                break;
582         default:
583             /* WAIT_FAILED? WAIT_ABANDONED? others? */
584             Perl_croak_nocontext("panic: cond_timedwait (%ld)",GetLastError());
585             break;
586     }
587     MUTEX_LOCK(mut);
588     cond->waiters--;
589     return (got_it);
590 #  else
591 #    ifdef OS2
592     int rc, got_it = 0;
593     STRLEN n_a;
594
595     ABS2RELMILLI(abs);
596
597     if ((rc = DosResetEventSem(*cond,&n_a)) && (rc != ERROR_ALREADY_RESET))
598         Perl_rc = rc, croak_with_os2error("panic: cond_timedwait-reset");
599     MUTEX_UNLOCK(mut);
600     if (CheckOSError(DosWaitEventSem(*cond,abs))
601         && (rc != ERROR_INTERRUPT))
602         croak_with_os2error("panic: cond_timedwait");
603     if (rc == ERROR_INTERRUPT) errno = EINTR;
604     MUTEX_LOCK(mut);
605     return (got_it);
606 #    else         /* Hope you're I_PTHREAD! */
607     struct timespec ts;
608     int got_it = 0;
609
610     ts.tv_sec = (long)abs;
611     abs -= (NV)ts.tv_sec;
612     ts.tv_nsec = (long)(abs * 1000000000.0);
613
614     switch (pthread_cond_timedwait(cond, mut, &ts)) {
615         case 0:         got_it = 1; break;
616         case ETIMEDOUT:             break;
617 #ifdef OEMVS
618         case -1:
619             if (errno == ETIMEDOUT || errno == EAGAIN)
620                 break;
621 #endif
622         default:
623             Perl_croak_nocontext("panic: cond_timedwait");
624             break;
625     }
626     return (got_it);
627 #    endif /* OS2 */
628 #  endif /* WIN32 */
629 #endif /* NETWARE || FAKE_THREADS || I_MACH_CTHREADS */
630 }
631
632
633 /* Given a shared RV, copy it's value to a private RV, also copying the
634  * object status of the referent.
635  * If the private side is already an appropriate RV->SV combination, keep
636  * it if possible.
637  */
638 STATIC void
639 S_get_RV(pTHX_ SV *sv, SV *ssv) {
640     SV *sobj = SvRV(ssv);
641     SV *obj;
642     if (! (SvROK(sv) &&
643            ((obj = SvRV(sv))) &&
644            (Perl_sharedsv_find(aTHX_ obj) == sobj) &&
645            (SvTYPE(obj) == SvTYPE(sobj))))
646     {
647         /* Can't reuse obj */
648         if (SvROK(sv)) {
649             SvREFCNT_dec(SvRV(sv));
650         } else {
651             assert(SvTYPE(sv) >= SVt_RV);
652             sv_setsv_nomg(sv, &PL_sv_undef);
653             SvROK_on(sv);
654         }
655         obj = S_sharedsv_new_private(aTHX_ SvRV(ssv));
656         SvRV_set(sv, obj);
657     }
658
659     if (SvOBJECT(obj)) {
660         /* Remove any old blessing */
661         SvREFCNT_dec(SvSTASH(obj));
662         SvOBJECT_off(obj);
663     }
664     if (SvOBJECT(sobj)) {
665         /* Add any new old blessing */
666         STRLEN len;
667         char* stash_ptr = SvPV((SV*) SvSTASH(sobj), len);
668         HV* stash = gv_stashpvn(stash_ptr, len, TRUE);
669         SvOBJECT_on(obj);
670         SvSTASH_set(obj, (HV*)SvREFCNT_inc(stash));
671     }
672 }
673
674
675 /* ------------ PERL_MAGIC_shared_scalar(n) functions -------------- */
676
677 /* Get magic for PERL_MAGIC_shared_scalar(n) */
678
679 int
680 sharedsv_scalar_mg_get(pTHX_ SV *sv, MAGIC *mg)
681 {
682     SV *ssv = (SV *) mg->mg_ptr;
683     assert(ssv);
684
685     ENTER_LOCK;
686     if (SvROK(ssv)) {
687         S_get_RV(aTHX_ sv, ssv);
688     } else {
689         sv_setsv_nomg(sv, ssv);
690     }
691     LEAVE_LOCK;
692     return (0);
693 }
694
695 /* Copy the contents of a private SV to a shared SV.
696  * Used by various mg_set()-type functions.
697  * Assumes lock is held.
698  */
699 void
700 sharedsv_scalar_store(pTHX_ SV *sv, SV *ssv)
701 {
702     dTHXc;
703     bool allowed = TRUE;
704
705     assert(PL_sharedsv_lock.owner == aTHX);
706     if (SvROK(sv)) {
707         SV *obj = SvRV(sv);
708         SV *sobj = Perl_sharedsv_find(aTHX_ obj);
709         if (sobj) {
710             SHARED_CONTEXT;
711             SvUPGRADE(ssv, SVt_RV);
712             sv_setsv_nomg(ssv, &PL_sv_undef);
713
714             SvRV_set(ssv, SvREFCNT_inc(sobj));
715             SvROK_on(ssv);
716             if (SvOBJECT(sobj)) {
717                 /* Remove any old blessing */
718                 SvREFCNT_dec(SvSTASH(sobj));
719                 SvOBJECT_off(sobj);
720             }
721             if (SvOBJECT(obj)) {
722               SV* fake_stash = newSVpv(HvNAME_get(SvSTASH(obj)),0);
723               SvOBJECT_on(sobj);
724               SvSTASH_set(sobj, (HV*)fake_stash);
725             }
726             CALLER_CONTEXT;
727         } else {
728             allowed = FALSE;
729         }
730     } else {
731         SvTEMP_off(sv);
732         SHARED_CONTEXT;
733         sv_setsv_nomg(ssv, sv);
734         if (SvOBJECT(ssv)) {
735             /* Remove any old blessing */
736             SvREFCNT_dec(SvSTASH(ssv));
737             SvOBJECT_off(ssv);
738         }
739         if (SvOBJECT(sv)) {
740           SV* fake_stash = newSVpv(HvNAME_get(SvSTASH(sv)),0);
741           SvOBJECT_on(ssv);
742           SvSTASH_set(ssv, (HV*)fake_stash);
743         }
744         CALLER_CONTEXT;
745     }
746     if (!allowed) {
747         Perl_croak(aTHX_ "Invalid value for shared scalar");
748     }
749 }
750
751 /* Set magic for PERL_MAGIC_shared_scalar(n) */
752
753 int
754 sharedsv_scalar_mg_set(pTHX_ SV *sv, MAGIC *mg)
755 {
756     SV *ssv = (SV*)(mg->mg_ptr);
757     assert(ssv);
758     ENTER_LOCK;
759     if (SvTYPE(ssv) < SvTYPE(sv)) {
760         dTHXc;
761         SHARED_CONTEXT;
762         sv_upgrade(ssv, SvTYPE(sv));
763         CALLER_CONTEXT;
764     }
765     sharedsv_scalar_store(aTHX_ sv, ssv);
766     LEAVE_LOCK;
767     return (0);
768 }
769
770 /* Free magic for PERL_MAGIC_shared_scalar(n) */
771
772 int
773 sharedsv_scalar_mg_free(pTHX_ SV *sv, MAGIC *mg)
774 {
775     S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);
776     return (0);
777 }
778
779 /*
780  * Called during cloning of PERL_MAGIC_shared_scalar(n) magic in new thread
781  */
782 int
783 sharedsv_scalar_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
784 {
785     SvREFCNT_inc_void(mg->mg_ptr);
786     return (0);
787 }
788
789 #ifdef MGf_LOCAL
790 /*
791  * Called during local $shared
792  */
793 int
794 sharedsv_scalar_mg_local(pTHX_ SV* nsv, MAGIC *mg)
795 {
796     MAGIC *nmg;
797     SV *ssv = (SV *) mg->mg_ptr;
798     if (ssv) {
799         ENTER_LOCK;
800         SvREFCNT_inc_void(ssv);
801         LEAVE_LOCK;
802     }
803     nmg = sv_magicext(nsv, mg->mg_obj, mg->mg_type, mg->mg_virtual,
804                            mg->mg_ptr, mg->mg_len);
805     nmg->mg_flags   = mg->mg_flags;
806     nmg->mg_private = mg->mg_private;
807
808     return (0);
809 }
810 #endif
811
812 MGVTBL sharedsv_scalar_vtbl = {
813     sharedsv_scalar_mg_get,     /* get */
814     sharedsv_scalar_mg_set,     /* set */
815     0,                          /* len */
816     0,                          /* clear */
817     sharedsv_scalar_mg_free,    /* free */
818     0,                          /* copy */
819     sharedsv_scalar_mg_dup,     /* dup */
820 #ifdef MGf_LOCAL
821     sharedsv_scalar_mg_local,   /* local */
822 #endif
823 };
824
825 /* ------------ PERL_MAGIC_tiedelem(p) functions -------------- */
826
827 /* Get magic for PERL_MAGIC_tiedelem(p) */
828
829 int
830 sharedsv_elem_mg_FETCH(pTHX_ SV *sv, MAGIC *mg)
831 {
832     dTHXc;
833     SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);
834     SV** svp;
835
836     ENTER_LOCK;
837     if (SvTYPE(saggregate) == SVt_PVAV) {
838         assert ( mg->mg_ptr == 0 );
839         SHARED_CONTEXT;
840         svp = av_fetch((AV*) saggregate, mg->mg_len, 0);
841     } else {
842         char *key = mg->mg_ptr;
843         STRLEN len = mg->mg_len;
844         assert ( mg->mg_ptr != 0 );
845         if (mg->mg_len == HEf_SVKEY) {
846            key = SvPV((SV *) mg->mg_ptr, len);
847         }
848         SHARED_CONTEXT;
849         svp = hv_fetch((HV*) saggregate, key, len, 0);
850     }
851     CALLER_CONTEXT;
852     if (svp) {
853         /* Exists in the array */
854         if (SvROK(*svp)) {
855             S_get_RV(aTHX_ sv, *svp);
856         } else {
857             /* XXX Can this branch ever happen? DAPM */
858             /* XXX assert("no such branch"); */
859             Perl_sharedsv_associate(aTHX_ sv, *svp);
860             sv_setsv(sv, *svp);
861         }
862     } else {
863         /* Not in the array */
864         sv_setsv(sv, &PL_sv_undef);
865     }
866     LEAVE_LOCK;
867     return (0);
868 }
869
870 /* Set magic for PERL_MAGIC_tiedelem(p) */
871
872 int
873 sharedsv_elem_mg_STORE(pTHX_ SV *sv, MAGIC *mg)
874 {
875     dTHXc;
876     SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);
877     SV **svp;
878     /* Theory - SV itself is magically shared - and we have ordered the
879        magic such that by the time we get here it has been stored
880        to its shared counterpart
881      */
882     ENTER_LOCK;
883     assert(saggregate);
884     if (SvTYPE(saggregate) == SVt_PVAV) {
885         assert ( mg->mg_ptr == 0 );
886         SHARED_CONTEXT;
887         svp = av_fetch((AV*) saggregate, mg->mg_len, 1);
888     } else {
889         char *key = mg->mg_ptr;
890         STRLEN len = mg->mg_len;
891         assert ( mg->mg_ptr != 0 );
892         if (mg->mg_len == HEf_SVKEY)
893            key = SvPV((SV *) mg->mg_ptr, len);
894         SHARED_CONTEXT;
895         svp = hv_fetch((HV*) saggregate, key, len, 1);
896     }
897     CALLER_CONTEXT;
898     Perl_sharedsv_associate(aTHX_ sv, *svp);
899     sharedsv_scalar_store(aTHX_ sv, *svp);
900     LEAVE_LOCK;
901     return (0);
902 }
903
904 /* Clear magic for PERL_MAGIC_tiedelem(p) */
905
906 int
907 sharedsv_elem_mg_DELETE(pTHX_ SV *sv, MAGIC *mg)
908 {
909     dTHXc;
910     MAGIC *shmg;
911     SV *saggregate = S_sharedsv_from_obj(aTHX_ mg->mg_obj);
912     ENTER_LOCK;
913     sharedsv_elem_mg_FETCH(aTHX_ sv, mg);
914     if ((shmg = mg_find(sv, PERL_MAGIC_shared_scalar)))
915         sharedsv_scalar_mg_get(aTHX_ sv, shmg);
916     if (SvTYPE(saggregate) == SVt_PVAV) {
917         SHARED_CONTEXT;
918         av_delete((AV*) saggregate, mg->mg_len, G_DISCARD);
919     } else {
920         char *key = mg->mg_ptr;
921         STRLEN len = mg->mg_len;
922         assert ( mg->mg_ptr != 0 );
923         if (mg->mg_len == HEf_SVKEY)
924            key = SvPV((SV *) mg->mg_ptr, len);
925         SHARED_CONTEXT;
926         hv_delete((HV*) saggregate, key, len, G_DISCARD);
927     }
928     CALLER_CONTEXT;
929     LEAVE_LOCK;
930     return (0);
931 }
932
933 /* Called during cloning of PERL_MAGIC_tiedelem(p) magic in new
934  * thread */
935
936 int
937 sharedsv_elem_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
938 {
939     SvREFCNT_inc_void(S_sharedsv_from_obj(aTHX_ mg->mg_obj));
940     assert(mg->mg_flags & MGf_DUP);
941     return (0);
942 }
943
944 MGVTBL sharedsv_elem_vtbl = {
945     sharedsv_elem_mg_FETCH,     /* get */
946     sharedsv_elem_mg_STORE,     /* set */
947     0,                          /* len */
948     sharedsv_elem_mg_DELETE,    /* clear */
949     0,                          /* free */
950     0,                          /* copy */
951     sharedsv_elem_mg_dup,       /* dup */
952 #ifdef MGf_LOCAL
953     0,                          /* local */
954 #endif
955 };
956
957 /* ------------ PERL_MAGIC_tied(P) functions -------------- */
958
959 /* Len magic for PERL_MAGIC_tied(P) */
960
961 U32
962 sharedsv_array_mg_FETCHSIZE(pTHX_ SV *sv, MAGIC *mg)
963 {
964     dTHXc;
965     SV *ssv = (SV *) mg->mg_ptr;
966     U32 val;
967     SHARED_EDIT;
968     if (SvTYPE(ssv) == SVt_PVAV) {
969         val = av_len((AV*) ssv);
970     } else {
971         /* Not actually defined by tie API but ... */
972         val = HvKEYS((HV*) ssv);
973     }
974     SHARED_RELEASE;
975     return (val);
976 }
977
978 /* Clear magic for PERL_MAGIC_tied(P) */
979
980 int
981 sharedsv_array_mg_CLEAR(pTHX_ SV *sv, MAGIC *mg)
982 {
983     dTHXc;
984     SV *ssv = (SV *) mg->mg_ptr;
985     SHARED_EDIT;
986     if (SvTYPE(ssv) == SVt_PVAV) {
987         av_clear((AV*) ssv);
988     } else {
989         hv_clear((HV*) ssv);
990     }
991     SHARED_RELEASE;
992     return (0);
993 }
994
995 /* Free magic for PERL_MAGIC_tied(P) */
996
997 int
998 sharedsv_array_mg_free(pTHX_ SV *sv, MAGIC *mg)
999 {
1000     S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);
1001     return (0);
1002 }
1003
1004 /*
1005  * Copy magic for PERL_MAGIC_tied(P)
1006  * This is called when perl is about to access an element of
1007  * the array -
1008  */
1009 int
1010 sharedsv_array_mg_copy(pTHX_ SV *sv, MAGIC* mg,
1011                        SV *nsv, const char *name, int namlen)
1012 {
1013     MAGIC *nmg = sv_magicext(nsv,mg->mg_obj,
1014                             toLOWER(mg->mg_type),&sharedsv_elem_vtbl,
1015                             name, namlen);
1016     nmg->mg_flags |= MGf_DUP;
1017     return (1);
1018 }
1019
1020 /* Called during cloning of PERL_MAGIC_tied(P) magic in new thread */
1021
1022 int
1023 sharedsv_array_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
1024 {
1025     SvREFCNT_inc_void((SV*)mg->mg_ptr);
1026     assert(mg->mg_flags & MGf_DUP);
1027     return (0);
1028 }
1029
1030 MGVTBL sharedsv_array_vtbl = {
1031     0,                          /* get */
1032     0,                          /* set */
1033     sharedsv_array_mg_FETCHSIZE,/* len */
1034     sharedsv_array_mg_CLEAR,    /* clear */
1035     sharedsv_array_mg_free,     /* free */
1036     sharedsv_array_mg_copy,     /* copy */
1037     sharedsv_array_mg_dup,      /* dup */
1038 #ifdef MGf_LOCAL
1039     0,                          /* local */
1040 #endif
1041 };
1042
1043
1044 /* Recursively unlocks a shared sv. */
1045
1046 void
1047 Perl_sharedsv_unlock(pTHX_ SV *ssv)
1048 {
1049     user_lock *ul = S_get_userlock(aTHX_ ssv, 0);
1050     assert(ul);
1051     recursive_lock_release(aTHX_ &ul->lock);
1052 }
1053
1054
1055 /* Recursive locks on a sharedsv.
1056  * Locks are dynamically scoped at the level of the first lock.
1057  */
1058 void
1059 Perl_sharedsv_lock(pTHX_ SV *ssv)
1060 {
1061     user_lock *ul;
1062     if (! ssv)
1063         return;
1064     ul = S_get_userlock(aTHX_ ssv, 1);
1065     recursive_lock_acquire(aTHX_ &ul->lock, __FILE__, __LINE__);
1066 }
1067
1068 /* Handles calls from lock() builtin via PL_lockhook */
1069
1070 void
1071 Perl_sharedsv_locksv(pTHX_ SV *sv)
1072 {
1073     SV *ssv;
1074
1075     if (SvROK(sv))
1076         sv = SvRV(sv);
1077     ssv = Perl_sharedsv_find(aTHX_ sv);
1078     if (!ssv)
1079        croak("lock can only be used on shared values");
1080     Perl_sharedsv_lock(aTHX_ ssv);
1081 }
1082
1083
1084 /* Saves a space for keeping SVs wider than an interpreter. */
1085
1086 void
1087 Perl_sharedsv_init(pTHX)
1088 {
1089     dTHXc;
1090     /* This pair leaves us in shared context ... */
1091     PL_sharedsv_space = perl_alloc();
1092     perl_construct(PL_sharedsv_space);
1093     CALLER_CONTEXT;
1094     recursive_lock_init(aTHX_ &PL_sharedsv_lock);
1095     PL_lockhook = &Perl_sharedsv_locksv;
1096     PL_sharehook = &Perl_sharedsv_share;
1097 }
1098
1099 #endif /* USE_ITHREADS */
1100
1101 MODULE = threads::shared        PACKAGE = threads::shared::tie
1102
1103 PROTOTYPES: DISABLE
1104
1105 #ifdef USE_ITHREADS
1106
1107 void
1108 PUSH(SV *obj, ...)
1109     CODE:
1110         dTHXc;
1111         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1112         int i;
1113         for (i = 1; i < items; i++) {
1114             SV* tmp = newSVsv(ST(i));
1115             SV *stmp;
1116             ENTER_LOCK;
1117             stmp = S_sharedsv_new_shared(aTHX_ tmp);
1118             sharedsv_scalar_store(aTHX_ tmp, stmp);
1119             SHARED_CONTEXT;
1120             av_push((AV*) sobj, stmp);
1121             SvREFCNT_inc_void(stmp);
1122             SHARED_RELEASE;
1123             SvREFCNT_dec(tmp);
1124         }
1125
1126
1127 void
1128 UNSHIFT(SV *obj, ...)
1129     CODE:
1130         dTHXc;
1131         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1132         int i;
1133         ENTER_LOCK;
1134         SHARED_CONTEXT;
1135         av_unshift((AV*)sobj, items - 1);
1136         CALLER_CONTEXT;
1137         for (i = 1; i < items; i++) {
1138             SV *tmp = newSVsv(ST(i));
1139             SV *stmp = S_sharedsv_new_shared(aTHX_ tmp);
1140             sharedsv_scalar_store(aTHX_ tmp, stmp);
1141             SHARED_CONTEXT;
1142             av_store((AV*) sobj, i - 1, stmp);
1143             SvREFCNT_inc_void(stmp);
1144             CALLER_CONTEXT;
1145             SvREFCNT_dec(tmp);
1146         }
1147         LEAVE_LOCK;
1148
1149
1150 void
1151 POP(SV *obj)
1152     CODE:
1153         dTHXc;
1154         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1155         SV* ssv;
1156         ENTER_LOCK;
1157         SHARED_CONTEXT;
1158         ssv = av_pop((AV*)sobj);
1159         CALLER_CONTEXT;
1160         ST(0) = sv_newmortal();
1161         Perl_sharedsv_associate(aTHX_ ST(0), ssv);
1162         SvREFCNT_dec(ssv);
1163         LEAVE_LOCK;
1164         /* XSRETURN(1); - implied */
1165
1166
1167 void
1168 SHIFT(SV *obj)
1169     CODE:
1170         dTHXc;
1171         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1172         SV* ssv;
1173         ENTER_LOCK;
1174         SHARED_CONTEXT;
1175         ssv = av_shift((AV*)sobj);
1176         CALLER_CONTEXT;
1177         ST(0) = sv_newmortal();
1178         Perl_sharedsv_associate(aTHX_ ST(0), ssv);
1179         SvREFCNT_dec(ssv);
1180         LEAVE_LOCK;
1181         /* XSRETURN(1); - implied */
1182
1183
1184 void
1185 EXTEND(SV *obj, IV count)
1186     CODE:
1187         dTHXc;
1188         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1189         SHARED_EDIT;
1190         av_extend((AV*)sobj, count);
1191         SHARED_RELEASE;
1192
1193
1194 void
1195 STORESIZE(SV *obj,IV count)
1196     CODE:
1197         dTHXc;
1198         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1199         SHARED_EDIT;
1200         av_fill((AV*) sobj, count);
1201         SHARED_RELEASE;
1202
1203
1204 void
1205 EXISTS(SV *obj, SV *index)
1206     CODE:
1207         dTHXc;
1208         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1209         bool exists;
1210         if (SvTYPE(sobj) == SVt_PVAV) {
1211             SHARED_EDIT;
1212             exists = av_exists((AV*) sobj, SvIV(index));
1213         } else {
1214             STRLEN len;
1215             char *key = SvPV(index,len);
1216             SHARED_EDIT;
1217             exists = hv_exists((HV*) sobj, key, len);
1218         }
1219         SHARED_RELEASE;
1220         ST(0) = (exists) ? &PL_sv_yes : &PL_sv_no;
1221         /* XSRETURN(1); - implied */
1222
1223
1224 void
1225 FIRSTKEY(SV *obj)
1226     CODE:
1227         dTHXc;
1228         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1229         char* key = NULL;
1230         I32 len = 0;
1231         HE* entry;
1232         ENTER_LOCK;
1233         SHARED_CONTEXT;
1234         hv_iterinit((HV*) sobj);
1235         entry = hv_iternext((HV*) sobj);
1236         if (entry) {
1237             key = hv_iterkey(entry,&len);
1238             CALLER_CONTEXT;
1239             ST(0) = sv_2mortal(newSVpv(key, len));
1240         } else {
1241             CALLER_CONTEXT;
1242             ST(0) = &PL_sv_undef;
1243         }
1244         LEAVE_LOCK;
1245         /* XSRETURN(1); - implied */
1246
1247
1248 void
1249 NEXTKEY(SV *obj, SV *oldkey)
1250     CODE:
1251         dTHXc;
1252         SV *sobj = S_sharedsv_from_obj(aTHX_ obj);
1253         char* key = NULL;
1254         I32 len = 0;
1255         HE* entry;
1256         ENTER_LOCK;
1257         SHARED_CONTEXT;
1258         entry = hv_iternext((HV*) sobj);
1259         if (entry) {
1260             key = hv_iterkey(entry,&len);
1261             CALLER_CONTEXT;
1262             ST(0) = sv_2mortal(newSVpv(key, len));
1263         } else {
1264             CALLER_CONTEXT;
1265             ST(0) = &PL_sv_undef;
1266         }
1267         LEAVE_LOCK;
1268         /* XSRETURN(1); - implied */
1269
1270
1271 MODULE = threads::shared        PACKAGE = threads::shared
1272
1273 PROTOTYPES: ENABLE
1274
1275 void
1276 _id(SV *ref)
1277     PROTOTYPE: \[$@%]
1278     PREINIT:
1279         SV *ssv;
1280     CODE:
1281         ref = SvRV(ref);
1282         if (SvROK(ref))
1283             ref = SvRV(ref);
1284         ssv = Perl_sharedsv_find(aTHX_ ref);
1285         if (! ssv)
1286             XSRETURN_UNDEF;
1287         ST(0) = sv_2mortal(newSVuv(PTR2UV(ssv)));
1288         /* XSRETURN(1); - implied */
1289
1290
1291 void
1292 _refcnt(SV *ref)
1293     PROTOTYPE: \[$@%]
1294     PREINIT:
1295         SV *ssv;
1296     CODE:
1297         ref = SvRV(ref);
1298         if (SvROK(ref))
1299             ref = SvRV(ref);
1300         ssv = Perl_sharedsv_find(aTHX_ ref);
1301         if (! ssv) {
1302             Perl_warn(aTHX_ "%" SVf " is not shared", ST(0));
1303             XSRETURN_UNDEF;
1304         }
1305         ST(0) = sv_2mortal(newSViv(SvREFCNT(ssv)));
1306         /* XSRETURN(1); - implied */
1307
1308
1309 void
1310 share(SV *ref)
1311     PROTOTYPE: \[$@%]
1312     CODE:
1313         if (! SvROK(ref))
1314             Perl_croak(aTHX_ "Argument to share needs to be passed as ref");
1315         ref = SvRV(ref);
1316         if (SvROK(ref))
1317             ref = SvRV(ref);
1318         Perl_sharedsv_share(aTHX_ ref);
1319         ST(0) = sv_2mortal(newRV_inc(ref));
1320         /* XSRETURN(1); - implied */
1321
1322
1323 void
1324 cond_wait(SV *ref_cond, SV *ref_lock = 0)
1325     PROTOTYPE: \[$@%];\[$@%]
1326     PREINIT:
1327         SV *ssv;
1328         perl_cond* user_condition;
1329         int locks;
1330         user_lock *ul;
1331     CODE:
1332         if (!SvROK(ref_cond))
1333             Perl_croak(aTHX_ "Argument to cond_wait needs to be passed as ref");
1334         ref_cond = SvRV(ref_cond);
1335         if (SvROK(ref_cond))
1336             ref_cond = SvRV(ref_cond);
1337         ssv = Perl_sharedsv_find(aTHX_ ref_cond);
1338         if (! ssv)
1339             Perl_croak(aTHX_ "cond_wait can only be used on shared values");
1340         ul = S_get_userlock(aTHX_ ssv, 1);
1341
1342         user_condition = &ul->user_cond;
1343         if (ref_lock && (ref_cond != ref_lock)) {
1344             if (!SvROK(ref_lock))
1345                 Perl_croak(aTHX_ "cond_wait lock needs to be passed as ref");
1346             ref_lock = SvRV(ref_lock);
1347             if (SvROK(ref_lock)) ref_lock = SvRV(ref_lock);
1348             ssv = Perl_sharedsv_find(aTHX_ ref_lock);
1349             if (! ssv)
1350                 Perl_croak(aTHX_ "cond_wait lock must be a shared value");
1351             ul = S_get_userlock(aTHX_ ssv, 1);
1352         }
1353         if (ul->lock.owner != aTHX)
1354             croak("You need a lock before you can cond_wait");
1355
1356         /* Stealing the members of the lock object worries me - NI-S */
1357         MUTEX_LOCK(&ul->lock.mutex);
1358         ul->lock.owner = NULL;
1359         locks = ul->lock.locks;
1360         ul->lock.locks = 0;
1361
1362         /* Since we are releasing the lock here, we need to tell other
1363          * people that it is ok to go ahead and use it */
1364         COND_SIGNAL(&ul->lock.cond);
1365         COND_WAIT(user_condition, &ul->lock.mutex);
1366         while (ul->lock.owner != NULL) {
1367             /* OK -- must reacquire the lock */
1368             COND_WAIT(&ul->lock.cond, &ul->lock.mutex);
1369         }
1370         ul->lock.owner = aTHX;
1371         ul->lock.locks = locks;
1372         MUTEX_UNLOCK(&ul->lock.mutex);
1373
1374
1375 int
1376 cond_timedwait(SV *ref_cond, double abs, SV *ref_lock = 0)
1377     PROTOTYPE: \[$@%]$;\[$@%]
1378     PREINIT:
1379         SV *ssv;
1380         perl_cond* user_condition;
1381         int locks;
1382         user_lock *ul;
1383     CODE:
1384         if (! SvROK(ref_cond))
1385             Perl_croak(aTHX_ "Argument to cond_timedwait needs to be passed as ref");
1386         ref_cond = SvRV(ref_cond);
1387         if (SvROK(ref_cond))
1388             ref_cond = SvRV(ref_cond);
1389         ssv = Perl_sharedsv_find(aTHX_ ref_cond);
1390         if (! ssv)
1391             Perl_croak(aTHX_ "cond_timedwait can only be used on shared values");
1392         ul = S_get_userlock(aTHX_ ssv, 1);
1393
1394         user_condition = &ul->user_cond;
1395         if (ref_lock && (ref_cond != ref_lock)) {
1396             if (! SvROK(ref_lock))
1397                 Perl_croak(aTHX_ "cond_timedwait lock needs to be passed as ref");
1398             ref_lock = SvRV(ref_lock);
1399             if (SvROK(ref_lock)) ref_lock = SvRV(ref_lock);
1400             ssv = Perl_sharedsv_find(aTHX_ ref_lock);
1401             if (! ssv)
1402                 Perl_croak(aTHX_ "cond_timedwait lock must be a shared value");
1403             ul = S_get_userlock(aTHX_ ssv, 1);
1404         }
1405         if (ul->lock.owner != aTHX)
1406             Perl_croak(aTHX_ "You need a lock before you can cond_wait");
1407
1408         MUTEX_LOCK(&ul->lock.mutex);
1409         ul->lock.owner = NULL;
1410         locks = ul->lock.locks;
1411         ul->lock.locks = 0;
1412         /* Since we are releasing the lock here, we need to tell other
1413          * people that it is ok to go ahead and use it */
1414         COND_SIGNAL(&ul->lock.cond);
1415         RETVAL = Perl_sharedsv_cond_timedwait(user_condition, &ul->lock.mutex, abs);
1416         while (ul->lock.owner != NULL) {
1417             /* OK -- must reacquire the lock... */
1418             COND_WAIT(&ul->lock.cond, &ul->lock.mutex);
1419         }
1420         ul->lock.owner = aTHX;
1421         ul->lock.locks = locks;
1422         MUTEX_UNLOCK(&ul->lock.mutex);
1423
1424         if (RETVAL == 0)
1425             XSRETURN_UNDEF;
1426     OUTPUT:
1427         RETVAL
1428
1429
1430 void
1431 cond_signal(SV *ref)
1432     PROTOTYPE: \[$@%]
1433     PREINIT:
1434         SV *ssv;
1435         user_lock *ul;
1436     CODE:
1437         if (! SvROK(ref))
1438             Perl_croak(aTHX_ "Argument to cond_signal needs to be passed as ref");
1439         ref = SvRV(ref);
1440         if (SvROK(ref))
1441             ref = SvRV(ref);
1442         ssv = Perl_sharedsv_find(aTHX_ ref);
1443         if (! ssv)
1444             Perl_croak(aTHX_ "cond_signal can only be used on shared values");
1445         ul = S_get_userlock(aTHX_ ssv, 1);
1446         if (ckWARN(WARN_THREADS) && ul->lock.owner != aTHX) {
1447             Perl_warner(aTHX_ packWARN(WARN_THREADS),
1448                             "cond_signal() called on unlocked variable");
1449         }
1450         COND_SIGNAL(&ul->user_cond);
1451
1452
1453 void
1454 cond_broadcast(SV *ref)
1455     PROTOTYPE: \[$@%]
1456     PREINIT:
1457         SV *ssv;
1458         user_lock *ul;
1459     CODE:
1460         if (! SvROK(ref))
1461             Perl_croak(aTHX_ "Argument to cond_broadcast needs to be passed as ref");
1462         ref = SvRV(ref);
1463         if (SvROK(ref))
1464             ref = SvRV(ref);
1465         ssv = Perl_sharedsv_find(aTHX_ ref);
1466         if (! ssv)
1467             Perl_croak(aTHX_ "cond_broadcast can only be used on shared values");
1468         ul = S_get_userlock(aTHX_ ssv, 1);
1469         if (ckWARN(WARN_THREADS) && ul->lock.owner != aTHX) {
1470             Perl_warner(aTHX_ packWARN(WARN_THREADS),
1471                             "cond_broadcast() called on unlocked variable");
1472         }
1473         COND_BROADCAST(&ul->user_cond);
1474
1475
1476 void
1477 bless(SV* ref, ...);
1478     PROTOTYPE: $;$
1479     PREINIT:
1480         HV* stash;
1481         SV *ssv;
1482     CODE:
1483         if (items == 1) {
1484             stash = CopSTASH(PL_curcop);
1485         } else {
1486             SV* classname = ST(1);
1487             STRLEN len;
1488             char *ptr;
1489
1490             if (classname &&
1491                 ! SvGMAGICAL(classname) &&
1492                 ! SvAMAGIC(classname) &&
1493                 SvROK(classname))
1494             {
1495                 Perl_croak(aTHX_ "Attempt to bless into a reference");
1496             }
1497             ptr = SvPV(classname, len);
1498             if (ckWARN(WARN_MISC) && len == 0) {
1499                 Perl_warner(aTHX_ packWARN(WARN_MISC),
1500                         "Explicit blessing to '' (assuming package main)");
1501             }
1502             stash = gv_stashpvn(ptr, len, TRUE);
1503         }
1504         SvREFCNT_inc_void(ref);
1505         (void)sv_bless(ref, stash);
1506         ST(0) = sv_2mortal(ref);
1507         ssv = Perl_sharedsv_find(aTHX_ ref);
1508         if (ssv) {
1509             dTHXc;
1510             ENTER_LOCK;
1511             SHARED_CONTEXT;
1512             {
1513                 SV* fake_stash = newSVpv(HvNAME_get(stash), 0);
1514                 (void)sv_bless(ssv, (HV*)fake_stash);
1515             }
1516             CALLER_CONTEXT;
1517             LEAVE_LOCK;
1518         }
1519         /* XSRETURN(1); - implied */
1520
1521 #endif /* USE_ITHREADS */
1522
1523 BOOT:
1524 {
1525 #ifdef USE_ITHREADS
1526      Perl_sharedsv_init(aTHX);
1527 #endif /* USE_ITHREADS */
1528 }