• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_CFTYPE_UNIQUE_REF_H
15 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_CFTYPE_UNIQUE_REF_H
16 #include <grpc/support/port_platform.h>
17 
18 #ifdef GPR_APPLE
19 #include <AvailabilityMacros.h>
20 #ifdef AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER
21 
22 #include <CoreFoundation/CoreFoundation.h>
23 
24 namespace grpc_event_engine {
25 namespace experimental {
26 
27 template <typename T>
28 class CFTypeUniqueRef {
29   static_assert(std::is_convertible<T, CFTypeRef>::value,
30                 "T should be `CFXxxRef` type");
31 
32  public:
33   /* implicit */
cf_type_ref_(cf_type_ref)34   CFTypeUniqueRef(T cf_type_ref = nullptr) : cf_type_ref_(cf_type_ref) {}
~CFTypeUniqueRef()35   ~CFTypeUniqueRef() { reset(); }
36 
37   CFTypeUniqueRef(CFTypeUniqueRef const&) = delete;
38   CFTypeUniqueRef& operator=(CFTypeUniqueRef const&) = delete;
39 
CFTypeUniqueRef(CFTypeUniqueRef && other)40   CFTypeUniqueRef(CFTypeUniqueRef&& other) : cf_type_ref_(other.release()) {};
41   CFTypeUniqueRef& operator=(CFTypeUniqueRef&& other) {
42     reset(other.release());
43     return *this;
44   }
45 
T()46   operator T() { return cf_type_ref_; }
47 
48   // Note: this is for passing a CFTypeRef as output parameter to a CF API, the
49   // current ref is released (if any) regardless of whether new value is set
50   T* operator&() {
51     reset();
52     return &cf_type_ref_;
53   }
54 
release()55   T release() {
56     T old = cf_type_ref_;
57     cf_type_ref_ = nullptr;
58     return old;
59   }
60 
61   void reset(T other = nullptr) {
62     if (cf_type_ref_ == other) {
63       return;
64     }
65     T old = cf_type_ref_;
66     cf_type_ref_ = other;
67     if (old) {
68       CFRelease(old);
69     }
70   }
71 
72  private:
73   T cf_type_ref_;
74 };
75 
76 }  // namespace experimental
77 }  // namespace grpc_event_engine
78 
79 #endif  // AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER
80 #endif  // GPR_APPLE
81 
82 #endif  // GRPC_SRC_CORE_LIB_EVENT_ENGINE_CF_ENGINE_CFTYPE_UNIQUE_REF_H
83