| Index: mozilla/security/nss/lib/base/tracker.c
|
| ===================================================================
|
| --- mozilla/security/nss/lib/base/tracker.c (revision 191424)
|
| +++ mozilla/security/nss/lib/base/tracker.c (working copy)
|
| @@ -1,415 +0,0 @@
|
| -/* This Source Code Form is subject to the terms of the Mozilla Public
|
| - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -
|
| -#ifdef DEBUG
|
| -static const char CVS_ID[] = "@(#) $RCSfile: tracker.c,v $ $Revision: 1.8 $ $Date: 2012/04/25 14:49:26 $";
|
| -#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
|
| -/*
|
| - * 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 = PR_CallOnceWithArg(&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;
|
| -
|
| - 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 */
|
|
|