Bug 1389967 In MinGW, work around a pointer to a function thunk disappearing when we unload nssckbi r?franziskus
MozReview-Commit-ID: 8Y09kTFUVIQ
old mode 100644
new mode 100755
--- a/nsprpub/pr/include/prthread.h
+++ b/nsprpub/pr/include/prthread.h
@@ -187,16 +187,33 @@ NSPR_API(const char *) PR_GetThreadName(
** allowed.
*/
typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
PRUintn *newIndex, PRThreadPrivateDTOR destructor);
/*
+** This function is redundant. It performs the same thing as the above
+** function when called like so:
+** PR_NewThreadPrivateIndex(newIndex, PR_Free);
+**
+** However, this function passes a function pointer that is within its
+** own module, and on MinGW _that_ behaves differently than passing a
+** function pointer in a different module because MinGW has
+** -mnop-fun-dllimport specified, which generates function thunks for
+** cross-module calls. And when a module (like nssckbi) gets unloaded,
+** and you try to call into that thunk (which is now missing) you'll
+** crash. So we do this bit of ugly to avoid that crash. Fortunately
+** this is the only place we've had to do this.
+*/
+NSPR_API(PRStatus) PR_NewThreadPrivateIndexWithPR_Free(
+ PRUintn *newIndex);
+
+/*
** Define some per-thread-private data.
** "tpdIndex" is an index into the per-thread private data table
** "priv" is the per-thread-private data
**
** If the per-thread private data table has a previously registered
** destructor function and a non-NULL per-thread-private data value,
** the destructor function is invoked.
**
--- a/nsprpub/pr/src/threads/prtpd.c
+++ b/nsprpub/pr/src/threads/prtpd.c
@@ -116,16 +116,22 @@ PR_IMPLEMENT(PRStatus) PR_NewThreadPriva
_pr_tpd_destructors[index] = dtor; /* record destructor @index */
*newIndex = (PRUintn)index; /* copy into client's location */
rv = PR_SUCCESS; /* that's okay */
}
return rv;
}
+PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndexWithPR_Free(
+ PRUintn *newIndex)
+{
+ return PR_NewThreadPrivateIndex(newIndex, PR_Free);
+}
+
/*
** Define some per-thread-private data.
** "index" is an index into the per-thread private data table
** "priv" is the per-thread-private data
**
** If the per-thread private data table has a previously registered
** destructor function and a non-NULL per-thread-private data value,
** the destructor function is invoked.
--- a/security/nss/lib/base/error.c
+++ b/security/nss/lib/base/error.c
@@ -60,17 +60,17 @@ static const PRCallOnceType error_call_a
/*
* error_once_function
*
* This is the once-called callback.
*/
static PRStatus
error_once_function(void)
{
- return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
+ return PR_NewThreadPrivateIndexWithPR_Free(&error_stack_index);
}
/*
* error_get_my_stack
*
* This routine returns the calling thread's error stack, creating
* it if necessary. It may return NULL upon error, which implicitly
* means that it ran out of memory.