/* * t4storagereg.cpp -- * * Implementation of the the T4Graph storage registry. * * Authors: Jacob Levy and Jean-Claude Wippler. * jyl@best.com jcw@equi4.com * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "t4graphrep.h" /* * Mutex protecting the storage registry: */ TCL_DECLARE_MUTEX(storageRegistryMutex) /* * This variable holds the global storage registry. It is protected from * multiple concurrent access by the above mutex. */ static Tcl_HashTable *storageRegistry = NULL; /* * Initialize the storage registry (in a thread safe manner). Returns * a boolean indicating whether this call was the one that set up the * registry. */ bool T4Graph_InitStorageRegistry() { bool settingUp = false; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry == NULL) { settingUp = true; storageRegistry = (Tcl_HashTable *) Tcl_Alloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(storageRegistry, TCL_ONE_WORD_KEYS); } Tcl_MutexUnlock(storageRegistryMutex); return settingUp; } /* * Destroy the storage registry. */ void T4Graph_DestroyStorageRegistry() { Tcl_MutexLock(storageRegistryMutex); if (storageRegistry != NULL) { Tcl_DeleteHashTable(storageRegistry); Tcl_Free((char *) storageRegistry); storageRegistry = NULL; } Tcl_MutexUnlock(storageRegistryMutex); } /* * Iterate over all registered storages. This function starts the iteration, * returns the first storage and stores the iteration information in the * passed Tcl_HashSearch argument. */ T4Storage * T4Graph_FirstStorage(Tcl_HashSearch *searchp) { Tcl_HashEntry *ep; T4Storage *sp = NULL; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry == NULL) { Tcl_MutexUnlock(storageRegistryMutex); return NULL; } ep = Tcl_FirstHashEntry(storageRegistry, searchp); if (ep != NULL) { sp = (T4Storage *) Tcl_GetHashValue(ep); } Tcl_MutexUnlock(storageRegistryMutex); return sp; } /* * This function iterates to the next registered storage. */ T4Storage * T4Graph_NextStorage(Tcl_HashSearch *searchp) { Tcl_HashEntry *ep; T4Storage *sp = NULL; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry == NULL) { Tcl_MutexUnlock(storageRegistryMutex); return NULL; } ep = Tcl_NextHashEntry(searchp); if (ep != NULL) { sp = (T4Storage *) Tcl_GetHashValue(ep); } Tcl_MutexUnlock(storageRegistryMutex); return sp; } /* * Find a T4Storage via its unique ID, if it's been registered. */ T4Storage * T4Graph_FindRegisteredStorage(int id) { Tcl_HashEntry *ep; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry == NULL) { Tcl_MutexUnlock(storageRegistryMutex); return NULL; } ep = Tcl_FindHashEntry(storageRegistry, (const char *) id); Tcl_MutexUnlock(storageRegistryMutex); if (ep == NULL) { return NULL; } return (T4Storage *) Tcl_GetHashValue(ep); } /* * Create, register and return a T4Storage. If the storage is already * registered, return that one. */ T4Storage * T4Graph_RegisterStorage(e4_Storage s, char *fnm, char *dnm) { Tcl_HashEntry *ep; int id = s.GetTemporaryUID(); int isnew; T4Storage *sp; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry == NULL) { Tcl_MutexUnlock(storageRegistryMutex); return NULL; } ep = Tcl_CreateHashEntry(storageRegistry, (const char *) id, &isnew); if (!isnew) { Tcl_MutexUnlock(storageRegistryMutex); return (T4Storage *) Tcl_GetHashValue(ep); } sp = new T4Storage(s, fnm, dnm); Tcl_SetHashValue(ep, sp); Tcl_MutexUnlock(storageRegistryMutex); return sp; } /* * Unregister a storage given its ID. */ void T4Graph_UnregisterStorage(int id) { Tcl_HashEntry *ep; Tcl_MutexLock(storageRegistryMutex); if (storageRegistry != NULL) { ep = Tcl_FindHashEntry(storageRegistry, (const char *) id); if (ep != NULL) { Tcl_DeleteHashEntry(ep); } } Tcl_MutexUnlock(storageRegistryMutex); }