Index: ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc |
=================================================================== |
--- ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc (revision 0) |
+++ ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc (revision 0) |
@@ -0,0 +1,89 @@ |
+// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "native_client/src/shared/ppapi_proxy/proxy_var_cache.h" |
+ |
+#include <limits> |
+#include <map> |
+ |
+#include "native_client/src/include/ref_counted.h" |
+#include "native_client/src/untrusted/pthread/pthread.h" |
+ |
+namespace ppapi_proxy { |
+ |
+namespace { |
+ |
+pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; |
+ |
+} // namespace |
+ |
+ProxyVarCache* ProxyVarCache::cache_singleton = NULL; |
+ |
+ProxyVarCache& ProxyVarCache::GetInstance() { |
+ // When the deprecated scripting is removed, this crash should disappear. |
+ // static ProxyVarCache cache_singleton; |
+ // return cache_singleton; |
+ pthread_mutex_lock(&mu); |
+ if (cache_singleton == NULL) |
+ cache_singleton = new ProxyVarCache(); |
+ pthread_mutex_unlock(&mu); |
+ return *cache_singleton; |
+} |
+ |
+void ProxyVarCache::RetainSharedProxyVar(const SharedProxyVar& proxy_var) { |
+ pthread_mutex_lock(&mu); |
+ // This implements "insert if absent, retain if present". |
+ std::pair<ProxyVarDictionary::iterator, bool> insert_result = |
+ proxy_var_cache_.insert( |
+ std::pair<int64_t, SharedProxyVar>(proxy_var->id(), proxy_var)); |
+ if (!insert_result.second) { |
+ // Object already exists, bump the retain count. |
+ insert_result.first->second->AddRef(); |
+ } |
+ pthread_mutex_unlock(&mu); |
+} |
+ |
+void ProxyVarCache::RetainProxyVar(const PP_Var& var) { |
+ if (!IsCachedType(var)) |
+ return; |
+ pthread_mutex_lock(&mu); |
+ ProxyVarDictionary::iterator iter = proxy_var_cache_.find(var.value.as_id); |
+ if (iter != proxy_var_cache_.end()) { |
+ iter->second->AddRef(); |
+ } |
+ pthread_mutex_unlock(&mu); |
+} |
+ |
+void ProxyVarCache::ReleaseProxyVar(const PP_Var& var) { |
+ if (!IsCachedType(var)) |
+ return; |
+ pthread_mutex_lock(&mu); |
+ ProxyVarDictionary::iterator iter = proxy_var_cache_.find(var.value.as_id); |
+ if (iter != proxy_var_cache_.end()) { |
+ // Decrement the reference count by one, as requested. |
+ iter->second->Release(); |
+ // All var reference count updating happens while mu is held, so the |
+ // potential race between HasOneRef and AddRef/Release cannot materialize. |
+ if (iter->second->HasOneRef()) { |
+ // If there is only one reference, it must be from the dictionary. |
+ // Delete the dictionary entry. |
+ proxy_var_cache_.erase(iter); |
+ } |
+ } |
+ pthread_mutex_unlock(&mu); |
+} |
+ |
+SharedProxyVar ProxyVarCache::SharedProxyVarForVar(PP_Var pp_var) const { |
+ SharedProxyVar proxy_var; |
+ pthread_mutex_lock(&mu); |
+ ProxyVarDictionary::const_iterator iter = |
+ proxy_var_cache_.find(pp_var.value.as_id); |
+ if (iter != proxy_var_cache_.end()) { |
+ proxy_var = iter->second; |
+ } |
+ pthread_mutex_unlock(&mu); |
+ return proxy_var; |
+} |
+ |
+} // namespace ppapi_proxy |