I'm using a map as a thread specific cache to keep track of failed LDAP searches. I dynamically allocate the map and store the pointer using pthread_setspecific. When checking the cache or incrementing the failure count I use pthred_getspecific in order to retrieve the void* pointer and static_cast the pointer back to my map type. Calls to the map using the [] operator don't appear to affect the state of the map and calls to map->size() always return 0. It feels like I'm probably incorrectly using pthread_getspecific but from the examples I've looked at my code looks right.
Code:
typedef std::map<std::string, int> FailedSearchCacheMap;
/**
* Create the keyserver failed search cache key. Only called
* internally and may only be called once per thread.
*/
static void
sCreateKeyserverFailedSearchCache(void)
{
// Create the key used in refrencing the cache.
// sFreeKeyserverFailedSearch called against the pointer when the thread exits
pthread_key_create(&sFailedSearchCacheKey, sFreeFailedSearchCache);
}
/**
* Get the keyserver failed search cache (also create one if it doesn't exist)
*/
static FailedSearchCacheMap *
sGetKeyserverFailedSearch(void)
{
// Initializes the failed search cache key.
// pthread_once guarantees that the create key routine is only called once
static pthread_once_t sKeyserverFailedSearchOnce = PTHREAD_ONCE_INIT;
pthread_once(&sKeyserverFailedSearchOnce, sCreateKeyserverFailedSearchCache);
FailedSearchCacheMap* cache = static_cast<FailedSearchCacheMap *>(pthread_getspecific(sFailedSearchCacheKey));
if (IsNull(cache))
{
cache = new FailedSearchCacheMap();
pthread_setspecific(sFailedSearchCacheKey, cache);
}
return cache;
}
Test Code:
FailedSearchCacheMap* map_ptr1 = sGetKeyserverFailedSearch();
FailedSearchCacheMap* map_ptr2 = sGetKeyserverFailedSearch();
std::string ks("hostname");
FailedSearchCacheMap map1 = *map_ptr1;
FailedSearchCacheMap map2 = *map_ptr2;
int numFailedSearches = map1[ks] + 1;
map1[ks] = numFailedSearches;
std::cout << "numFailedSearches: " << numFailedSearches << std::endl;
std::cout << "map_ptr1 address: " << map_ptr1 << std::endl;
std::cout << "map_ptr2 address: " << map_ptr2 << std::endl;
std::cout << "map_ptr1->size(): " << map_ptr1->size() << std::endl;
std::cout << "map_ptr2->size(): " << map_ptr2->size() << std::endl;
std::cout << "map1.size(): " << map1.size() << std::endl;
std::cout << "map2.size(): " << map2.size() << std::endl;
FailedSearchCacheMap::iterator i = map1.begin();
for(; i != map1.end(); i++)
std::cout << (*i).first << ":" << (*i).second << std::endl;
Test Code Output:
numFailedSearches: 1
map_ptr1 address: 0x909ce88
map_ptr2 address: 0x909ce88
map_ptr1->size(): 0
map_ptr2->size(): 0
map1.size(): 1
map2.size(): 0
hostname:1