STATIC bool
S_invoke_exception_hook(pTHX_ SV *ex, bool warn)
{
+ dVAR;
HV *stash;
GV *gv;
CV *cv;
#ifndef PERL_GLOBAL_STRUCT_PRIVATE
void *
-Perl_my_cxt_init(pTHX_ int *index, size_t size)
+Perl_my_cxt_init(pTHX_ int *indexp, size_t size)
{
dVAR;
void *p;
+ int index;
+
PERL_ARGS_ASSERT_MY_CXT_INIT;
- if (*index == -1) {
- /* this module hasn't been allocated an index yet */
+
+ index = *indexp;
+ /* do initial check without locking.
+ * -1: not allocated or another thread currently allocating
+ * other: already allocated by another thread
+ */
+ if (index == -1) {
MUTEX_LOCK(&PL_my_ctx_mutex);
- *index = PL_my_cxt_index++;
+ /*now a stricter check with locking */
+ index = *indexp;
+ if (index == -1)
+ /* this module hasn't been allocated an index yet */
+ *indexp = PL_my_cxt_index++;
+ index = *indexp;
MUTEX_UNLOCK(&PL_my_ctx_mutex);
}
-
+
/* make sure the array is big enough */
- if (PL_my_cxt_size <= *index) {
+ if (PL_my_cxt_size <= index) {
if (PL_my_cxt_size) {
IV new_size = PL_my_cxt_size;
- while (new_size <= *index)
+ while (new_size <= index)
new_size *= 2;
Renew(PL_my_cxt_list, new_size, void *);
PL_my_cxt_size = new_size;
}
/* newSV() allocates one more than needed */
p = (void*)SvPVX(newSV(size-1));
- PL_my_cxt_list[*index] = p;
+ PL_my_cxt_list[index] = p;
Zero(p, size, char);
return p;
}
PERL_ARGS_ASSERT_MY_CXT_INIT;
index = Perl_my_cxt_index(aTHX_ my_cxt_key);
+ /* do initial check without locking.
+ * -1: not allocated or another thread currently allocating
+ * other: already allocated by another thread
+ */
if (index == -1) {
- /* this module hasn't been allocated an index yet */
MUTEX_LOCK(&PL_my_ctx_mutex);
- index = PL_my_cxt_index++;
+ /*now a stricter check with locking */
+ index = Perl_my_cxt_index(aTHX_ my_cxt_key);
+ if (index == -1)
+ /* this module hasn't been allocated an index yet */
+ index = PL_my_cxt_index++;
+
+ /* Store the index in a global MY_CXT_KEY string to index mapping
+ * table. This emulates the perl-module static my_cxt_index var on
+ * builds which don't allow static vars */
+ if (PL_my_cxt_keys_size <= index) {
+ int old_size = PL_my_cxt_keys_size;
+ int i;
+ if (PL_my_cxt_keys_size) {
+ IV new_size = PL_my_cxt_keys_size;
+ while (new_size <= index)
+ new_size *= 2;
+ PL_my_cxt_keys = (const char **)PerlMemShared_realloc(
+ PL_my_cxt_keys,
+ new_size * sizeof(const char *));
+ PL_my_cxt_keys_size = new_size;
+ }
+ else {
+ PL_my_cxt_keys_size = 16;
+ PL_my_cxt_keys = (const char **)PerlMemShared_malloc(
+ PL_my_cxt_keys_size * sizeof(const char *));
+ }
+ for (i = old_size; i < PL_my_cxt_keys_size; i++) {
+ PL_my_cxt_keys[i] = 0;
+ }
+ }
+ PL_my_cxt_keys[index] = my_cxt_key;
+
MUTEX_UNLOCK(&PL_my_ctx_mutex);
}
while (new_size <= index)
new_size *= 2;
Renew(PL_my_cxt_list, new_size, void *);
- Renew(PL_my_cxt_keys, new_size, const char *);
PL_my_cxt_size = new_size;
}
else {
PL_my_cxt_size = 16;
Newx(PL_my_cxt_list, PL_my_cxt_size, void *);
- Newx(PL_my_cxt_keys, PL_my_cxt_size, const char *);
}
for (i = old_size; i < PL_my_cxt_size; i++) {
- PL_my_cxt_keys[i] = 0;
PL_my_cxt_list[i] = 0;
}
}
- PL_my_cxt_keys[index] = my_cxt_key;
/* newSV() allocates one more than needed */
p = (void*)SvPVX(newSV(size-1));
PL_my_cxt_list[index] = p;