summaryrefslogtreecommitdiff
path: root/security/nss/lib/base/tracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/base/tracker.c')
-rw-r--r--security/nss/lib/base/tracker.c544
1 files changed, 0 insertions, 544 deletions
diff --git a/security/nss/lib/base/tracker.c b/security/nss/lib/base/tracker.c
deleted file mode 100644
index 5198388a2..000000000
--- a/security/nss/lib/base/tracker.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-/*
- * tracker.c
- *
- * This file contains the code used by the pointer-tracking calls used
- * in the debug builds to catch bad pointers. The entire contents are
- * only available in debug builds (both internal and external builds).
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifdef DEBUG
-
-/*
- * call_once
- *
- * Unfortunately, NSPR's PR_CallOnce function doesn't accept a closure
- * variable. So I have a static version here which does. This code
- * is based on NSPR's, and uses the NSPR function to initialize the
- * required lock.
- */
-
-/*
- * The is the "once block" that's passed to the "real" PR_CallOnce
- * function, to call the local initializer myOnceFunction once.
- */
-static PRCallOnceType myCallOnce;
-
-/*
- * This structure is used by the call_once function to make sure that
- * any "other" threads calling the call_once don't return too quickly,
- * before the initializer has finished.
- */
-static struct {
- PZLock *ml;
- PZCondVar *cv;
-} mod_init;
-
-/*
- * This is the initializer for the above mod_init structure.
- */
-static PRStatus
-myOnceFunction
-(
- void
-)
-{
- mod_init.ml = PZ_NewLock(nssILockOther);
- if( (PZLock *)NULL == mod_init.ml ) {
- return PR_FAILURE;
- }
-
- mod_init.cv = PZ_NewCondVar(mod_init.ml);
- if( (PZCondVar *)NULL == mod_init.cv ) {
- PZ_DestroyLock(mod_init.ml);
- mod_init.ml = (PZLock *)NULL;
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * The nss call_once callback takes a closure argument.
- */
-typedef PRStatus (PR_CALLBACK *nssCallOnceFN)(void *arg);
-
-/*
- * NSS's call_once function.
- */
-static PRStatus
-call_once
-(
- PRCallOnceType *once,
- nssCallOnceFN func,
- void *arg
-)
-{
- PRStatus rv;
-
- if( !myCallOnce.initialized ) {
- rv = PR_CallOnce(&myCallOnce, myOnceFunction);
- if( PR_SUCCESS != rv ) {
- return rv;
- }
- }
-
- if( !once->initialized ) {
- if( 0 == PR_AtomicSet(&once->inProgress, 1) ) {
- once->status = (*func)(arg);
- PZ_Lock(mod_init.ml);
- once->initialized = 1;
- PZ_NotifyAllCondVar(mod_init.cv);
- PZ_Unlock(mod_init.ml);
- } else {
- PZ_Lock(mod_init.ml);
- while( !once->initialized ) {
- PZ_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
- }
- PZ_Unlock(mod_init.ml);
- }
- }
-
- return once->status;
-}
-
-/*
- * Now we actually get to my own "call once" payload function.
- * But wait, to create the hash, I need a hash function!
- */
-
-/*
- * identity_hash
- *
- * This static callback is a PLHashFunction as defined in plhash.h
- * It merely returns the value of the object pointer as its hash.
- * There are no possible errors.
- */
-
-static PLHashNumber PR_CALLBACK
-identity_hash
-(
- const void *key
-)
-{
- return (PLHashNumber)key;
-}
-
-/*
- * trackerOnceFunc
- *
- * This function is called once, using the nssCallOnce function above.
- * It creates a new pointer tracker object; initialising its hash
- * table and protective lock.
- */
-
-static PRStatus
-trackerOnceFunc
-(
- void *arg
-)
-{
- nssPointerTracker *tracker = (nssPointerTracker *)arg;
-
- tracker->lock = PZ_NewLock(nssILockOther);
- if( (PZLock *)NULL == tracker->lock ) {
- return PR_FAILURE;
- }
-
- tracker->table = PL_NewHashTable(0,
- identity_hash,
- PL_CompareValues,
- PL_CompareValues,
- (PLHashAllocOps *)NULL,
- (void *)NULL);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_DestroyLock(tracker->lock);
- tracker->lock = (PZLock *)NULL;
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_initialize
- *
- * This method is only present in debug builds.
- *
- * This routine initializes an nssPointerTracker object. Note that
- * the object must have been declared *static* to guarantee that it
- * is in a zeroed state initially. This routine is idempotent, and
- * may even be safely called by multiple threads simultaneously with
- * the same argument. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. On failure it will set an
- * error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_initialize
-(
- nssPointerTracker *tracker
-)
-{
- PRStatus rv = call_once(&tracker->once, trackerOnceFunc, tracker);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- }
-
- return rv;
-}
-
-#ifdef DONT_DESTROY_EMPTY_TABLES
-/* See same #ifdef below */
-/*
- * count_entries
- *
- * This static routine is a PLHashEnumerator, as defined in plhash.h.
- * It merely causes the enumeration function to count the number of
- * entries.
- */
-
-static PRIntn PR_CALLBACK
-count_entries
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
-{
- return HT_ENUMERATE_NEXT;
-}
-#endif /* DONT_DESTROY_EMPTY_TABLES */
-
-/*
- * zero_once
- *
- * This is a guaranteed zeroed once block. It's used to help clear
- * the tracker.
- */
-
-static const PRCallOnceType zero_once;
-
-/*
- * nssPointerTracker_finalize
- *
- * This method is only present in debug builds.
- *
- * This routine returns the nssPointerTracker object to the pre-
- * initialized state, releasing all resources used by the object.
- * It will *NOT* destroy the objects being tracked by the pointer
- * (should any remain), and therefore cannot be used to "sweep up"
- * remaining objects. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCES. On failure it will set an
- * error on the error stack and return PR_FAILURE. If any objects
- * remain in the tracker when it is finalized, that will be treated
- * as an error.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_TRACKER_NOT_EMPTY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_finalize
-(
- nssPointerTracker *tracker
-)
-{
- PZLock *lock;
- PRIntn count;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- lock = tracker->lock;
- PZ_Lock(lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
-#ifdef DONT_DESTROY_EMPTY_TABLES
- /*
- * I changed my mind; I think we don't want this after all.
- * Comments?
- */
- count = PL_HashTableEnumerateEntries(tracker->table,
- count_entries,
- (void *)NULL);
-
- if( 0 != count ) {
- PZ_Unlock(lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
- return PR_FAILURE;
- }
-#endif /* DONT_DESTROY_EMPTY_TABLES */
-
- PL_HashTableDestroy(tracker->table);
- /* memset(tracker, 0, sizeof(nssPointerTracker)); */
- tracker->once = zero_once;
- tracker->lock = (PZLock *)NULL;
- tracker->table = (PLHashTable *)NULL;
-
- PZ_Unlock(lock);
- PZ_DestroyLock(lock);
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_add
- *
- * This method is only present in debug builds.
- *
- * This routine adds the specified pointer to the nssPointerTracker
- * object. It should be called in constructor objects to register
- * new valid objects. The nssPointerTracker is threadsafe, but this
- * call is not idempotent. This routine returns a PRStatus value;
- * if successful it will return PR_SUCCESS. On failure it will set
- * an error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_DUPLICATE_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_add
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- void *check;
- PLHashEntry *entry;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- check = PL_HashTableLookup(tracker->table, pointer);
- if( (void *)NULL != check ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
- return PR_FAILURE;
- }
-
- entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
-
- PZ_Unlock(tracker->lock);
-
- if( (PLHashEntry *)NULL == entry ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_remove
- *
- * This method is only present in debug builds.
- *
- * This routine removes the specified pointer from the
- * nssPointerTracker object. It does not call any destructor for the
- * object; rather, this should be called from the object's destructor.
- * The nssPointerTracker is threadsafe, but this call is not
- * idempotent. This routine returns a PRStatus value; if successful
- * it will return PR_SUCCESS. On failure it will set an error on the
- * error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_remove
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- PRBool registered;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- registered = PL_HashTableRemove(tracker->table, pointer);
- PZ_Unlock(tracker->lock);
-
- if( !registered ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_verify
- *
- * This method is only present in debug builds.
- *
- * This routine verifies that the specified pointer has been registered
- * with the nssPointerTracker object. The nssPointerTracker object is
- * threadsafe, and this call may be safely called from multiple threads
- * simultaneously with the same arguments. This routine returns a
- * PRStatus value; if the pointer is registered this will return
- * PR_SUCCESS. Otherwise it will set an error on the error stack and
- * return PR_FAILURE. Although the error is suitable for leaving on
- * the stack, callers may wish to augment the information available by
- * placing a more type-specific error on the stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILRUE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_verify
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- void *check;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- check = PL_HashTableLookup(tracker->table, pointer);
- PZ_Unlock(tracker->lock);
-
- if( (void *)NULL == check ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-#endif /* DEBUG */