Index: generic/nsfPointer.c =================================================================== diff -u -r6b1a83846ee9bd80b7ce10d88cc427bdb5585819 -r42d2240c0949a258303e3213574aa96fd0ef4e1a --- generic/nsfPointer.c (.../nsfPointer.c) (revision 6b1a83846ee9bd80b7ce10d88cc427bdb5585819) +++ generic/nsfPointer.c (.../nsfPointer.c) (revision 42d2240c0949a258303e3213574aa96fd0ef4e1a) @@ -4,7 +4,7 @@ * Provide API for accessing mallocated data via Tcl. * this is used e.q. via the MongoDB interface. * - * Copyright (C) 2011 Gustaf Neumann + * Copyright (C) 2011-2014 Gustaf Neumann * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -53,6 +53,11 @@ Nsf_PointerAdd(Tcl_Interp *interp, char *buffer, CONST char *typeName, void *valuePtr) { int *counterPtr; + assert(interp); + assert(buffer); + assert(typeName); + assert(valuePtr); + counterPtr = Nsf_PointerTypeLookup(interp, typeName); if (counterPtr) { Tcl_DString ds, *dsPtr = &ds; @@ -95,10 +100,15 @@ * *---------------------------------------------------------------------- */ +static void * Nsf_PointerGet(char *key, CONST char *prefix) nonnull(1) nonnull(2); + static void * Nsf_PointerGet(char *key, CONST char *prefix) { void *valuePtr = NULL; + assert(key); + assert(prefix); + /* make sure to return the right type of hash entry */ if (strncmp(prefix, key, strlen(prefix)) == 0) { Tcl_HashEntry *hPtr; @@ -119,12 +129,12 @@ * * Nsf_PointerGetHptr -- * - * Find for a pointer the associated key. The current (static) - * implementaiton is quite slow in case there are a high number of - * pointer values registered (which should not be the case for the - * current usage patterns). It could certainly be improved by a - * second hash table. The function should be run under a callers - * mutex. + * Find for a pointer the associated key for a valuePtr (reverse + * lookup). The current implementation is quite slow in case there + * are a high number of pointer values registered (which should not + * be the case for the current usage patterns). It could certainly + * be improved by a second hash table. The function should be run + * under a callers mutex. * * Results: * key or NULL. @@ -134,11 +144,15 @@ * *---------------------------------------------------------------------- */ +static Tcl_HashEntry * Nsf_PointerGetHptr(void *valuePtr) nonnull(1); + static Tcl_HashEntry * Nsf_PointerGetHptr(void *valuePtr) { Tcl_HashEntry *hPtr; Tcl_HashSearch hSrch; + assert(valuePtr); + for (hPtr = Tcl_FirstHashEntry(pointerHashTablePtr, &hSrch); hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { void *ptr = Tcl_GetHashValue(hPtr); @@ -154,8 +168,8 @@ * * Nsf_PointerDelete -- * - * Delete an hash entry from our locally maintained hash table and - * free the associated memory, if the heas entry is + * Delete an hash entry from the locally maintained hash table and + * free the associated memory, if the hash entry is * found. Normally, the key should be provided. If the key is not * available, we perform a reverse lookup from the hash table. * @@ -209,11 +223,21 @@ *---------------------------------------------------------------------- */ +int Nsf_ConvertToPointer(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, + ClientData *clientData, Tcl_Obj **outObjPtr) + nonnull(1) nonnull(2) nonnull(3) nonnull(4) nonnull(5); + int Nsf_ConvertToPointer(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { void *valuePtr; + assert(interp); + assert(objPtr); + assert(pPtr); + assert(clientData); + assert(outObjPtr); + *outObjPtr = objPtr; valuePtr = Nsf_PointerGet(ObjStr(objPtr), pPtr->type); if (valuePtr) { @@ -243,6 +267,10 @@ Tcl_HashEntry *hPtr; int isNew; + assert(interp); + assert(typeName); + assert(counterPtr); + NsfMutexLock(&pointerMutex); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, typeName, &isNew); @@ -277,6 +305,9 @@ Nsf_PointerTypeLookup(Tcl_Interp *interp, CONST char* typeName) { Tcl_HashEntry *hPtr; + assert(interp); + assert(typeName); + NsfMutexLock(&pointerMutex); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, typeName, NULL); NsfMutexUnlock(&pointerMutex); @@ -305,22 +336,26 @@ void Nsf_PointerInit(Tcl_Interp *interp) { - NsfMutexLock(&pointerMutex); + assert(interp); - if (pointerTableRefCount == 0) { - Tcl_InitHashTable(pointerHashTablePtr, TCL_STRING_KEYS); - } - pointerTableRefCount++; + NsfMutexLock(&pointerMutex); - NsfMutexUnlock(&pointerMutex); + if (pointerTableRefCount == 0) { + Tcl_InitHashTable(pointerHashTablePtr, TCL_STRING_KEYS); + } + pointerTableRefCount++; + //fprintf(stderr, "Nsf_PointerInit pointerTableRefCount == %d\n", pointerTableRefCount); + + NsfMutexUnlock(&pointerMutex); + } /* *---------------------------------------------------------------------- * Nsf_PointerExit -- * - * Exit handler fr the Pointer converter + * Exit handler for the Pointer converter * * Results: * void @@ -334,31 +369,34 @@ void Nsf_PointerExit(Tcl_Interp *interp) { - NsfMutexLock(&pointerMutex); - if (--pointerTableRefCount == 0) { + assert(interp); - if (RUNTIME_STATE(interp)->debugLevel >= 2) { - Tcl_HashSearch hSrch; - Tcl_HashEntry *hPtr; + NsfMutexLock(&pointerMutex); + if (--pointerTableRefCount == 0) { - for (hPtr = Tcl_FirstHashEntry(pointerHashTablePtr, &hSrch); hPtr; - hPtr = Tcl_NextHashEntry(&hSrch)) { - char *key = Tcl_GetHashKey(pointerHashTablePtr, hPtr); - void *valuePtr = Tcl_GetHashValue(hPtr); + if (RUNTIME_STATE(interp)->debugLevel >= 2) { + Tcl_HashSearch hSrch; + Tcl_HashEntry *hPtr; - /* - * We can't use NsfLog here any more, since the Tcl procs are - * already deleted. - */ + for (hPtr = Tcl_FirstHashEntry(pointerHashTablePtr, &hSrch); hPtr; + hPtr = Tcl_NextHashEntry(&hSrch)) { + char *key = Tcl_GetHashKey(pointerHashTablePtr, hPtr); + void *valuePtr = Tcl_GetHashValue(hPtr); - fprintf(stderr, "Nsf_PointerExit: we have still an entry %s with value %p\n", key, valuePtr); - } - } + /* + * We can't use NsfLog here any more, since the Tcl procs are + * already deleted. + */ - Tcl_DeleteHashTable(pointerHashTablePtr); + fprintf(stderr, "Nsf_PointerExit: we have still an entry %s with value %p\n", key, valuePtr); + } } - NsfMutexUnlock(&pointerMutex); + Tcl_DeleteHashTable(pointerHashTablePtr); + } + //fprintf(stderr, "Nsf_PointerExit pointerTableRefCount == %d\n", pointerTableRefCount); + + NsfMutexUnlock(&pointerMutex); } /*