1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /* The CFStream handle acts as an event synchronization entity for
20  * read/write/open/error/eos events happening on CFStream streams. */
21 
22 #ifndef GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H
23 #define GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H
24 
25 #include <grpc/support/port_platform.h>
26 
27 #include "src/core/lib/iomgr/port.h"
28 
29 #ifdef GRPC_CFSTREAM
30 #import <CoreFoundation/CoreFoundation.h>
31 
32 #include "src/core/lib/gprpp/memory.h"
33 #include "src/core/lib/iomgr/closure.h"
34 #include "src/core/lib/iomgr/lockfree_event.h"
35 
36 class GrpcLibraryInitHolder {
37  public:
38   GrpcLibraryInitHolder();
39   virtual ~GrpcLibraryInitHolder();
40 };
41 
42 class CFStreamHandle : public GrpcLibraryInitHolder {
43  public:
44   static CFStreamHandle* CreateStreamHandle(CFReadStreamRef read_stream,
45                                             CFWriteStreamRef write_stream);
46   /** Use CreateStreamHandle function instead of using this directly. */
47   CFStreamHandle(CFReadStreamRef read_stream, CFWriteStreamRef write_stream);
48   CFStreamHandle(const CFStreamHandle& ref) = delete;
49   CFStreamHandle(CFStreamHandle&& ref) = delete;
50   CFStreamHandle& operator=(const CFStreamHandle& rhs) = delete;
51   ~CFStreamHandle() override;
52 
53   void NotifyOnOpen(grpc_closure* closure);
54   void NotifyOnRead(grpc_closure* closure);
55   void NotifyOnWrite(grpc_closure* closure);
56   void Shutdown(grpc_error* error);
57 
58   void Ref(const char* file = "", int line = 0, const char* reason = nullptr);
59   void Unref(const char* file = "", int line = 0, const char* reason = nullptr);
60 
61  private:
62   static void ReadCallback(CFReadStreamRef stream, CFStreamEventType type,
63                            void* client_callback_info);
64   static void WriteCallback(CFWriteStreamRef stream, CFStreamEventType type,
65                             void* client_callback_info);
66   static void* Retain(void* info);
67   static void Release(void* info);
68 
69   grpc_core::LockfreeEvent open_event_;
70   grpc_core::LockfreeEvent read_event_;
71   grpc_core::LockfreeEvent write_event_;
72 
73   dispatch_queue_t dispatch_queue_;
74 
75   gpr_refcount refcount_;
76 };
77 
78 #ifdef DEBUG
79 #define CFSTREAM_HANDLE_REF(handle, reason) \
80   (handle)->Ref(__FILE__, __LINE__, (reason))
81 #define CFSTREAM_HANDLE_UNREF(handle, reason) \
82   (handle)->Unref(__FILE__, __LINE__, (reason))
83 #else
84 #define CFSTREAM_HANDLE_REF(handle, reason) (handle)->Ref()
85 #define CFSTREAM_HANDLE_UNREF(handle, reason) (handle)->Unref()
86 #endif
87 
88 #endif
89 
90 #endif /* GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H */
91