|  | // Copyright (c) 2006- Facebook | 
|  | // Distributed under the Thrift Software License | 
|  | // | 
|  | // See accompanying file LICENSE or visit the Thrift site at: | 
|  | // http://developers.facebook.com/thrift/ | 
|  |  | 
|  | #include "FacebookBase.h" | 
|  |  | 
|  | using namespace facebook::fb303; | 
|  | using facebook::thrift::concurrency::Guard; | 
|  |  | 
|  | FacebookBase::FacebookBase(std::string name, get_static_limref_ptr reflect_lim) : | 
|  | name_(name) { | 
|  | aliveSince_ = (int64_t) time(NULL); | 
|  | if (reflect_lim) { | 
|  | reflect_lim(reflection_limited_); | 
|  | } | 
|  | } | 
|  |  | 
|  | inline void FacebookBase::getName(std::string& _return) { | 
|  | _return = name_; | 
|  | } | 
|  |  | 
|  | void FacebookBase::setOption(const std::string& key, const std::string& value) { | 
|  | Guard g(optionsLock_); | 
|  | options_[key] = value; | 
|  | } | 
|  |  | 
|  | void FacebookBase::getOption(std::string& _return, const std::string& key) { | 
|  | Guard g(optionsLock_); | 
|  | _return = options_[key]; | 
|  | } | 
|  |  | 
|  | void FacebookBase::getOptions(std::map<std::string, std::string> & _return) { | 
|  | Guard g(optionsLock_); | 
|  | _return = options_; | 
|  | } | 
|  |  | 
|  | int64_t FacebookBase::incrementCounter(const std::string& key, int64_t amount) { | 
|  | counters_.acquireRead(); | 
|  |  | 
|  | // if we didn't find the key, we need to write lock the whole map to create it | 
|  | ReadWriteCounterMap::iterator it = counters_.find(key); | 
|  | if (it == counters_.end()) { | 
|  | counters_.release(); | 
|  | counters_.acquireWrite(); | 
|  |  | 
|  | // we need to check again to make sure someone didn't create this key | 
|  | // already while we released the lock | 
|  | it = counters_.find(key); | 
|  | if(it == counters_.end()){ | 
|  | counters_[key].value = amount; | 
|  | counters_.release(); | 
|  | return amount; | 
|  | } | 
|  | } | 
|  |  | 
|  | it->second.acquireWrite(); | 
|  | int64_t count = it->second.value + amount; | 
|  | it->second.value = count; | 
|  | it->second.release(); | 
|  | counters_.release(); | 
|  | return count; | 
|  | } | 
|  |  | 
|  | int64_t FacebookBase::setCounter(const std::string& key, int64_t value) { | 
|  | counters_.acquireRead(); | 
|  |  | 
|  | // if we didn't find the key, we need to write lock the whole map to create it | 
|  | ReadWriteCounterMap::iterator it = counters_.find(key); | 
|  | if (it == counters_.end()) { | 
|  | counters_.release(); | 
|  | counters_.acquireWrite(); | 
|  | counters_[key].value = value; | 
|  | counters_.release(); | 
|  | return value; | 
|  | } | 
|  |  | 
|  | it->second.acquireWrite(); | 
|  | it->second.value = value; | 
|  | it->second.release(); | 
|  | counters_.release(); | 
|  | return value; | 
|  | } | 
|  |  | 
|  | void FacebookBase::getCounters(std::map<std::string, int64_t>& _return) { | 
|  | // we need to lock the whole thing and actually build the map since we don't | 
|  | // want our read/write structure to go over the wire | 
|  | counters_.acquireRead(); | 
|  | for(ReadWriteCounterMap::iterator it = counters_.begin(); | 
|  | it != counters_.end(); it++) | 
|  | { | 
|  | _return[it->first] = it->second.value; | 
|  | } | 
|  | counters_.release(); | 
|  | } | 
|  |  | 
|  | int64_t FacebookBase::getCounter(const std::string& key) { | 
|  | int64_t rv = 0; | 
|  | counters_.acquireRead(); | 
|  | ReadWriteCounterMap::iterator it = counters_.find(key); | 
|  | if (it != counters_.end()) { | 
|  | it->second.acquireRead(); | 
|  | rv = it->second.value; | 
|  | it->second.release(); | 
|  | } | 
|  | counters_.release(); | 
|  | return rv; | 
|  | } | 
|  |  | 
|  | inline int64_t FacebookBase::aliveSince() { | 
|  | return aliveSince_; | 
|  | } | 
|  |  |