summaryrefslogtreecommitdiff
path: root/sharedsv.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2001-08-13 12:45:21 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2001-08-13 12:45:21 +0000
commitcd1ee231f67664d7a2f2d53512a707d2736dbb0e (patch)
tree26d3be9ce06d827160183cf5272c57670329c2cb /sharedsv.c
parentf3faeb53b75c95d2773d14d859d4fa9ca1594daa (diff)
downloadperl-cd1ee231f67664d7a2f2d53512a707d2736dbb0e.tar.gz
[PATHC] sharedsv.[c|h]
From: "Artur Bergman" <artur@contiller.se> Date: Mon, 13 Aug 2001 14:38:41 +0200 Message-ID: <005401c123f4$e1f53360$21000a0a@vogw2kdev> Subject: [PATCH] embed.pl From: Arthur Bergman <arthur@contiller.se> Date: Mon, 13 Aug 2001 14:38:14 +0200 Message-ID: <B79D96D6.3088%arthur@contiller.se> Subject: [PATCH] sharedsv cleanups From: "Arthur Bergman" <arthur@contiller.se> Date: Mon, 13 Aug 2001 15:14:25 +0200 Message-ID: <005a01c123f9$dfe525d0$21000a0a@vogw2kdev> Plus few tweaks: _init needs to be Adp, the prototypes should not be revealed unless using ithreads, #endif FOO must be #endif /* FOO */, adding (parentheses) around do { } while doesn't work too well. p4raw-id: //depot/perl@11659
Diffstat (limited to 'sharedsv.c')
-rw-r--r--sharedsv.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/sharedsv.c b/sharedsv.c
new file mode 100644
index 0000000000..43596941de
--- /dev/null
+++ b/sharedsv.c
@@ -0,0 +1,201 @@
+/* sharedsv.c
+ *
+ * Copyright (c) 2001, Larry Wall
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+* Contributed by Arthur Bergman arthur@contiller.se
+*
+* "Hand any two wizards a piece of rope and they would instinctively pull in
+* opposite directions."
+* --Sourcery
+*
+*/
+
+#include "EXTERN.h"
+#define PERL_IN_SHAREDSV_C
+#include "perl.h"
+
+PerlInterpreter* sharedsv_space;
+
+#ifdef USE_ITHREADS
+
+/*
+ Shared SV
+
+ Shared SV is a structure for keeping the backend storage
+ of shared svs.
+
+ */
+
+/*
+=for apidoc sharedsv_init
+
+Saves a space for keeping SVs wider than an interpreter,
+currently only stores a pointer to the first interpreter.
+
+=cut
+*/
+
+void
+Perl_sharedsv_init(pTHX)
+{
+ sharedsv_space = PERL_GET_CONTEXT;
+}
+
+/*
+=for apidoc sharedsv_new
+
+Allocates a new shared sv struct, you must yourself create the SV/AV/HV.
+=cut
+*/
+
+shared_sv *
+Perl_sharedsv_new(pTHX)
+{
+ shared_sv* ssv;
+ New(2555,ssv,1,shared_sv);
+ MUTEX_INIT(&ssv->mutex);
+ COND_INIT(&ssv->cond);
+ ssv->locks = 0;
+ return ssv;
+}
+
+
+/*
+=for apidoc sharedsv_find
+
+Tries to find if a given SV has a shared backend, either by
+looking at magic, or by checking if it is tied again threads::shared.
+
+=cut
+*/
+
+shared_sv *
+Perl_sharedsv_find(pTHX_ SV* sv)
+{
+ /* does all it can to find a shared_sv struct, returns NULL otherwise */
+ shared_sv* ssv = NULL;
+ return ssv;
+}
+
+/*
+=for apidoc sharedsv_lock
+
+Recursive locks on a sharedsv.
+Locks are dynamicly scoped at the level of the first lock.
+=cut
+*/
+void
+Perl_sharedsv_lock(pTHX_ shared_sv* ssv)
+{
+ if(!ssv)
+ return;
+ if(ssv->owner && ssv->owner == my_perl) {
+ ssv->locks++;
+ return;
+ }
+ MUTEX_LOCK(&ssv->mutex);
+ ssv->locks++;
+ ssv->owner = my_perl;
+ if(ssv->locks == 1)
+ SAVEDESTRUCTOR_X(Perl_sharedsv_unlock_scope,ssv);
+}
+
+/*
+=for apidoc sharedsv_unlock
+
+Recursively unlocks a shared sv.
+
+=cut
+*/
+
+void
+Perl_sharedsv_unlock(pTHX_ shared_sv* ssv)
+{
+ if(ssv->owner != my_perl)
+ return;
+
+ if(--ssv->locks == 0) {
+ ssv->owner = NULL;
+ MUTEX_UNLOCK(&ssv->mutex);
+ }
+ }
+
+void
+Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv)
+{
+ if(ssv->owner != my_perl)
+ return;
+ ssv->locks = 0;
+ ssv->owner = NULL;
+ MUTEX_UNLOCK(&ssv->mutex);
+}
+
+/*
+=for apidoc sharedsv_thrcnt_inc
+
+Increments the threadcount of a sharedsv.
+=cut
+*/
+void
+Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv)
+{
+ SHAREDSvLOCK(ssv);
+ SvREFCNT_inc(ssv->sv);
+ SHAREDSvUNLOCK(ssv);
+}
+
+/*
+=for apidoc sharedsv_thrcnt_dec
+
+Decrements the threadcount of a shared sv. When a threads frontend is freed
+this function should be called.
+
+=cut
+*/
+
+void
+Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
+{
+ SV* sv;
+ SHAREDSvLOCK(ssv);
+ SHAREDSvEDIT(ssv);
+ sv = SHAREDSvGET(ssv);
+ if (SvREFCNT(sv) == 1) {
+ switch (SvTYPE(sv)) {
+ case SVt_RV:
+ if (SvROK(sv))
+ Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv *)SvIV(SvRV(sv)));
+ break;
+ case SVt_PVAV: {
+ SV **src_ary = AvARRAY((AV *)sv);
+ SSize_t items = AvFILLp((AV *)sv) + 1;
+
+ while (items-- > 0) {
+ if(SvTYPE(*src_ary))
+ Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv *)SvIV(*src_ary++));
+ }
+ break;
+ }
+ case SVt_PVHV: {
+ HE *entry;
+ (void)hv_iterinit((HV *)sv);
+ while ((entry = hv_iternext((HV *)sv)))
+ Perl_sharedsv_thrcnt_dec(
+ aTHX_ (shared_sv *)SvIV(hv_iterval((HV *)sv, entry))
+ );
+ break;
+ }
+ }
+ }
+ SvREFCNT_dec(sv);
+ SHAREDSvRELEASE(ssv);
+ SHAREDSvUNLOCK(ssv);
+}
+
+#endif