diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 19:18:52 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 19:18:52 +0000 |
commit | 47a961c13f61cdbd00a7020a5a8173586a8ed892 (patch) | |
tree | a89ea8f0c81f5c74cb5bcaf852e4e83ab21fbc75 /ppapi/proxy | |
parent | 8367f7b3aab8365ed5e696e4720a2a416d956d0a (diff) | |
download | chromium_src-47a961c13f61cdbd00a7020a5a8173586a8ed892.zip chromium_src-47a961c13f61cdbd00a7020a5a8173586a8ed892.tar.gz chromium_src-47a961c13f61cdbd00a7020a5a8173586a8ed892.tar.bz2 |
Add support for threadsafe completion callback factory.
This also makes the default be threadsafe. The old factory wasn't threadsafe even to the extent claimed in the header which was causing hangs in plugins
BUG=136284
Review URL: https://chromiumcodereview.appspot.com/10696157
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146611 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r-- | ppapi/proxy/ppb_audio_input_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_audio_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_broker_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_file_chooser_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_file_io_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_file_ref_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_file_system_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_flash_menu_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_2d_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_graphics_3d_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_instance_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_url_loader_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_capture_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_decoder_proxy.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/proxy_completion_callback_factory.h | 87 | ||||
-rw-r--r-- | ppapi/proxy/proxy_non_thread_safe_ref_count.h | 49 |
16 files changed, 115 insertions, 91 deletions
diff --git a/ppapi/proxy/ppb_audio_input_proxy.h b/ppapi/proxy/ppb_audio_input_proxy.h index 61125c6..f1fac75 100644 --- a/ppapi/proxy/ppb_audio_input_proxy.h +++ b/ppapi/proxy/ppb_audio_input_proxy.h @@ -16,7 +16,7 @@ #include "ppapi/c/dev/ppb_audio_input_dev.h" #include "ppapi/c/ppb_audio_config.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -85,8 +85,7 @@ class PPB_AudioInput_Proxy : public InterfaceProxy { base::SharedMemoryHandle* foreign_shared_memory_handle, uint32_t* shared_memory_length); - pp::CompletionCallbackFactory<PPB_AudioInput_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_AudioInput_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_AudioInput_Proxy); }; diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h index d8fe9a0..b516925 100644 --- a/ppapi/proxy/ppb_audio_proxy.h +++ b/ppapi/proxy/ppb_audio_proxy.h @@ -16,7 +16,7 @@ #include "ppapi/c/ppb_audio.h" #include "ppapi/c/ppb_audio_config.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -74,8 +74,7 @@ class PPB_Audio_Proxy : public InterfaceProxy { base::SharedMemoryHandle* foreign_shared_memory_handle, uint32_t* shared_memory_length); - pp::CompletionCallbackFactory<PPB_Audio_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Audio_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Proxy); }; diff --git a/ppapi/proxy/ppb_broker_proxy.h b/ppapi/proxy/ppb_broker_proxy.h index a04903c7..5bc195a 100644 --- a/ppapi/proxy/ppb_broker_proxy.h +++ b/ppapi/proxy/ppb_broker_proxy.h @@ -9,7 +9,7 @@ #include "ipc/ipc_platform_file.h" #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -41,8 +41,7 @@ class PPB_Broker_Proxy : public InterfaceProxy { void ConnectCompleteInHost(int32_t result, const ppapi::HostResource& host_resource); - pp::CompletionCallbackFactory<PPB_Broker_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Broker_Proxy> callback_factory_; }; } // namespace proxy diff --git a/ppapi/proxy/ppb_file_chooser_proxy.h b/ppapi/proxy/ppb_file_chooser_proxy.h index 825d7c9..1dc0921 100644 --- a/ppapi/proxy/ppb_file_chooser_proxy.h +++ b/ppapi/proxy/ppb_file_chooser_proxy.h @@ -12,7 +12,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/proxy_array_output.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/thunk/ppb_file_chooser_api.h" #include "ppapi/cpp/output_traits.h" @@ -64,8 +64,7 @@ class PPB_FileChooser_Proxy : public InterfaceProxy { scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output, HostResource chooser); - pp::CompletionCallbackFactory<PPB_FileChooser_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_FileChooser_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_FileChooser_Proxy); }; diff --git a/ppapi/proxy/ppb_file_io_proxy.h b/ppapi/proxy/ppb_file_io_proxy.h index 86d822c..10e5313 100644 --- a/ppapi/proxy/ppb_file_io_proxy.h +++ b/ppapi/proxy/ppb_file_io_proxy.h @@ -10,7 +10,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -82,8 +82,7 @@ class PPB_FileIO_Proxy : public InterfaceProxy { void ReadCallbackCompleteInHost(int32_t pp_error, const HostResource& host_resource, std::string* data); - pp::CompletionCallbackFactory<PPB_FileIO_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_FileIO_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Proxy); }; diff --git a/ppapi/proxy/ppb_file_ref_proxy.h b/ppapi/proxy/ppb_file_ref_proxy.h index d15536e..64febfa 100644 --- a/ppapi/proxy/ppb_file_ref_proxy.h +++ b/ppapi/proxy/ppb_file_ref_proxy.h @@ -12,7 +12,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_time.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -92,8 +92,7 @@ class PPB_FileRef_Proxy : public InterfaceProxy { const HostResource& host_resource, int callback_id); - pp::CompletionCallbackFactory<PPB_FileRef_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_FileRef_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_FileRef_Proxy); }; diff --git a/ppapi/proxy/ppb_file_system_proxy.h b/ppapi/proxy/ppb_file_system_proxy.h index 86eb48e..68197e7 100644 --- a/ppapi/proxy/ppb_file_system_proxy.h +++ b/ppapi/proxy/ppb_file_system_proxy.h @@ -13,7 +13,7 @@ #include "ppapi/c/pp_time.h" #include "ppapi/c/ppb_file_system.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" namespace ppapi { @@ -51,8 +51,7 @@ class PPB_FileSystem_Proxy : public InterfaceProxy { void OpenCompleteInHost(int32_t result, const ppapi::HostResource& host_resource); - pp::CompletionCallbackFactory<PPB_FileSystem_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_FileSystem_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_FileSystem_Proxy); }; diff --git a/ppapi/proxy/ppb_flash_menu_proxy.h b/ppapi/proxy/ppb_flash_menu_proxy.h index 8c20774..b9eda00 100644 --- a/ppapi/proxy/ppb_flash_menu_proxy.h +++ b/ppapi/proxy/ppb_flash_menu_proxy.h @@ -6,7 +6,7 @@ #define PPAPI_PPB_FLASH_MENU_PROXY_H_ #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/utility/completion_callback_factory.h" struct PP_Flash_Menu; @@ -46,8 +46,7 @@ class PPB_Flash_Menu_Proxy : public InterfaceProxy { int32_t result); void SendShowACKToPlugin(int32_t result, ShowRequest* request); - pp::CompletionCallbackFactory<PPB_Flash_Menu_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Flash_Menu_Proxy> callback_factory_; }; } // namespace proxy diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h index 45043ce..cf0a921 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.h +++ b/ppapi/proxy/ppb_graphics_2d_proxy.h @@ -13,7 +13,7 @@ #include "ppapi/c/pp_size.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/shared_impl/host_resource.h" #include "ppapi/utility/completion_callback_factory.h" @@ -66,8 +66,7 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy { void SendFlushACKToPlugin(int32_t result, const HostResource& graphics_2d); - pp::CompletionCallbackFactory<PPB_Graphics2D_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Graphics2D_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_Graphics2D_Proxy); }; diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h index 521d90e..d16053c 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.h +++ b/ppapi/proxy/ppb_graphics_3d_proxy.h @@ -12,7 +12,7 @@ #include "ppapi/c/pp_graphics_3d.h" #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/shared_impl/ppb_graphics_3d_shared.h" #include "ppapi/shared_impl/resource.h" #include "ppapi/utility/completion_callback_factory.h" @@ -106,8 +106,7 @@ class PPB_Graphics3D_Proxy : public InterfaceProxy { void SendSwapBuffersACKToPlugin(int32_t result, const HostResource& context); - pp::CompletionCallbackFactory<PPB_Graphics3D_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Graphics3D_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_Graphics3D_Proxy); }; diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h index 20dd60d..e2ac4d7 100644 --- a/ppapi/proxy/ppb_instance_proxy.h +++ b/ppapi/proxy/ppb_instance_proxy.h @@ -10,7 +10,7 @@ #include "ppapi/c/pp_time.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/shared_impl/host_resource.h" #include "ppapi/shared_impl/ppb_instance_shared.h" #include "ppapi/thunk/ppb_instance_api.h" @@ -194,8 +194,7 @@ class PPB_Instance_Proxy : public InterfaceProxy, void MouseLockCompleteInHost(int32_t result, PP_Instance instance); - pp::CompletionCallbackFactory<PPB_Instance_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_Instance_Proxy> callback_factory_; }; } // namespace proxy diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h index 7dea1e8..5fd924d 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.h +++ b/ppapi/proxy/ppb_url_loader_proxy.h @@ -14,7 +14,7 @@ #include "ppapi/c/ppb_url_loader.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/shared_impl/host_resource.h" #include "ppapi/utility/completion_callback_factory.h" @@ -86,8 +86,7 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { // Handles callback for everything but reads. void OnCallback(int32_t result, const HostResource& resource); - pp::CompletionCallbackFactory<PPB_URLLoader_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_URLLoader_Proxy> callback_factory_; // Valid only in the host, this lazily-initialized pointer indicates the // URLLoaderTrusted interface. diff --git a/ppapi/proxy/ppb_video_capture_proxy.h b/ppapi/proxy/ppb_video_capture_proxy.h index 2b86460..cf01875 100644 --- a/ppapi/proxy/ppb_video_capture_proxy.h +++ b/ppapi/proxy/ppb_video_capture_proxy.h @@ -10,7 +10,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/proxy/serialized_structs.h" #include "ppapi/shared_impl/ppb_device_ref_shared.h" #include "ppapi/utility/completion_callback_factory.h" @@ -64,8 +64,7 @@ class PPB_VideoCapture_Proxy : public InterfaceProxy { const ppapi::HostResource& resource); void OpenACKInHost(int32_t result, const ppapi::HostResource& resource); - pp::CompletionCallbackFactory<PPB_VideoCapture_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_VideoCapture_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_VideoCapture_Proxy); }; diff --git a/ppapi/proxy/ppb_video_decoder_proxy.h b/ppapi/proxy/ppb_video_decoder_proxy.h index 7461a1f..ffb259e 100644 --- a/ppapi/proxy/ppb_video_decoder_proxy.h +++ b/ppapi/proxy/ppb_video_decoder_proxy.h @@ -7,7 +7,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/proxy/proxy_completion_callback_factory.h" #include "ppapi/shared_impl/ppb_video_decoder_shared.h" #include "ppapi/thunk/ppb_video_decoder_api.h" #include "ppapi/utility/completion_callback_factory.h" @@ -67,8 +67,7 @@ class PPB_VideoDecoder_Proxy : public InterfaceProxy { void OnMsgFlushACK(const ppapi::HostResource& decoder, int32_t result); void OnMsgResetACK(const ppapi::HostResource& decoder, int32_t result); - pp::CompletionCallbackFactory<PPB_VideoDecoder_Proxy, - ProxyNonThreadSafeRefCount> callback_factory_; + ProxyCompletionCallbackFactory<PPB_VideoDecoder_Proxy> callback_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Proxy); }; diff --git a/ppapi/proxy/proxy_completion_callback_factory.h b/ppapi/proxy/proxy_completion_callback_factory.h new file mode 100644 index 0000000..1221f43 --- /dev/null +++ b/ppapi/proxy/proxy_completion_callback_factory.h @@ -0,0 +1,87 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_PROXY_COMPLETION_CALLBACK_FACTORY_H_ +#define PPAPI_PROXY_PROXY_COMPLETION_CALLBACK_FACTORY_H_ + +#include "base/logging.h" +#include "base/message_loop.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/utility/completion_callback_factory.h" + +namespace ppapi { +namespace proxy { + +// This class is just like pp::NonThreadSafeThreadTraits but rather than using +// pp::Module::core (which doesn't exist), it uses Chrome threads which do. +class ProxyNonThreadSafeThreadTraits { + public: + class RefCount { + public: + RefCount() : ref_(0) { +#ifndef NDEBUG + message_loop_ = MessageLoop::current(); +#endif + } + + ~RefCount() { +#ifndef NDEBUG + DCHECK(message_loop_ == MessageLoop::current()); +#endif + } + + int32_t AddRef() { +#ifndef NDEBUG + DCHECK(message_loop_ == MessageLoop::current()); +#endif + return ++ref_; + } + + int32_t Release() { +#ifndef NDEBUG + DCHECK(message_loop_ == MessageLoop::current()); +#endif + DCHECK(ref_ > 0); + return --ref_; + } + + private: + int32_t ref_; +#ifndef NDEBUG + MessageLoop* message_loop_; +#endif + }; + + // No-op lock class. + class Lock { + public: + Lock() {} + ~Lock() {} + + void Acquire() {} + void Release() {} + }; + + // No-op AutoLock class. + class AutoLock { + public: + explicit AutoLock(Lock&) {} + ~AutoLock() {} + }; +}; + +template<typename T> +class ProxyCompletionCallbackFactory + : public pp::CompletionCallbackFactory<T, ProxyNonThreadSafeThreadTraits> { + public: + ProxyCompletionCallbackFactory() + : pp::CompletionCallbackFactory<T, ProxyNonThreadSafeThreadTraits>() {} + ProxyCompletionCallbackFactory(T* t) + : pp::CompletionCallbackFactory<T, ProxyNonThreadSafeThreadTraits>(t) {} +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_PROXY_COMPLETION_CALLBACK_FACTORY_H_ diff --git a/ppapi/proxy/proxy_non_thread_safe_ref_count.h b/ppapi/proxy/proxy_non_thread_safe_ref_count.h deleted file mode 100644 index 855c87c..0000000 --- a/ppapi/proxy/proxy_non_thread_safe_ref_count.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PPAPI_PROXY_PROXY_NON_THREAD_SAFE_REF_COUNT_H_ -#define PPAPI_PROXY_PROXY_NON_THREAD_SAFE_REF_COUNT_H_ - -#include "base/message_loop.h" -#include "ppapi/cpp/completion_callback.h" - -namespace ppapi { -namespace proxy { - -// This class is just like ppapi/cpp/non_thread_safe_ref_count.h but rather -// than using pp::Module::core (which doesn't exist), it uses Chrome threads -// which do. -class ProxyNonThreadSafeRefCount { - public: - ProxyNonThreadSafeRefCount() : ref_(0) { -#ifndef NDEBUG - message_loop_ = MessageLoop::current(); -#endif - } - - ~ProxyNonThreadSafeRefCount() { - PP_DCHECK(message_loop_ == MessageLoop::current()); - } - - int32_t AddRef() { - PP_DCHECK(message_loop_ == MessageLoop::current()); - return ++ref_; - } - - int32_t Release() { - PP_DCHECK(message_loop_ == MessageLoop::current()); - return --ref_; - } - - private: - int32_t ref_; -#ifndef NDEBUG - MessageLoop* message_loop_; -#endif -}; - -} // namespace proxy -} // namespace ppapi - -#endif // PPAPI_PROXY_PROXY_NON_THREAD_SAFE_REF_COUNT_H_ |