Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : /// A completion queue implements a concurrent producer-consumer queue, with two
35 : /// main methods, \a Next and \a AsyncNext.
36 : #ifndef GRPCXX_COMPLETION_QUEUE_H
37 : #define GRPCXX_COMPLETION_QUEUE_H
38 :
39 : #include <grpc/support/time.h>
40 : #include <grpc++/impl/grpc_library.h>
41 : #include <grpc++/support/status.h>
42 : #include <grpc++/support/time.h>
43 :
44 : struct grpc_completion_queue;
45 :
46 : namespace grpc {
47 :
48 : template <class R>
49 : class ClientReader;
50 : template <class W>
51 : class ClientWriter;
52 : template <class R, class W>
53 : class ClientReaderWriter;
54 : template <class R>
55 : class ServerReader;
56 : template <class W>
57 : class ServerWriter;
58 : template <class R, class W>
59 : class ServerReaderWriter;
60 : template <class ServiceType, class RequestType, class ResponseType>
61 : class RpcMethodHandler;
62 : template <class ServiceType, class RequestType, class ResponseType>
63 : class ClientStreamingHandler;
64 : template <class ServiceType, class RequestType, class ResponseType>
65 : class ServerStreamingHandler;
66 : template <class ServiceType, class RequestType, class ResponseType>
67 : class BidiStreamingHandler;
68 : class UnknownMethodHandler;
69 :
70 : class Channel;
71 : class ClientContext;
72 : class CompletionQueueTag;
73 : class CompletionQueue;
74 : class RpcMethod;
75 : class Server;
76 : class ServerBuilder;
77 : class ServerContext;
78 :
79 : /// A thin wrapper around \a grpc_completion_queue (see / \a
80 : /// src/core/surface/completion_queue.h).
81 : class CompletionQueue : public GrpcLibrary {
82 : public:
83 : /// Default constructor. Implicitly creates a \a grpc_completion_queue
84 : /// instance.
85 : CompletionQueue();
86 :
87 : /// Wrap \a take, taking ownership of the instance.
88 : ///
89 : /// \param take The completion queue instance to wrap. Ownership is taken.
90 : explicit CompletionQueue(grpc_completion_queue* take);
91 :
92 : /// Destructor. Destroys the owned wrapped completion queue / instance.
93 : ~CompletionQueue() GRPC_OVERRIDE;
94 :
95 : /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
96 : enum NextStatus {
97 : SHUTDOWN, ///< The completion queue has been shutdown.
98 : GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
99 : ///< associated value; \a ok indicating its success.
100 : TIMEOUT ///< deadline was reached.
101 : };
102 :
103 : /// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
104 : /// Both \a tag and \a ok are updated upon success (if an event is available
105 : /// within the \a deadline). A \a tag points to an arbitrary location usually
106 : /// employed to uniquely identify an event.
107 : ///
108 : /// \param tag[out] Upon sucess, updated to point to the event's tag.
109 : /// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
110 : /// \param deadline[in] How long to block in wait for an event.
111 : ///
112 : /// \return The type of event read.
113 : template <typename T>
114 3427692 : NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
115 3427692 : TimePoint<T> deadline_tp(deadline);
116 3412137 : return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
117 : }
118 :
119 : /// Read from the queue, blocking until an event is available or the queue is
120 : /// shutting down.
121 : ///
122 : /// \param tag[out] Updated to point to the read event's tag.
123 : /// \param ok[out] true if read a regular event, false otherwise.
124 : ///
125 : /// \return true if read a regular event, false if the queue is shutting down.
126 2773165 : bool Next(void** tag, bool* ok) {
127 2773165 : return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
128 2771589 : SHUTDOWN);
129 : }
130 :
131 : /// Request the shutdown of the queue.
132 : ///
133 : /// \warning This method must be called at some point. Once invoked, \a Next
134 : /// will start to return false and \a AsyncNext will return \a
135 : /// NextStatus::SHUTDOWN. Only once either one of these methods does that
136 : /// (that is, once the queue has been \em drained) can an instance of this
137 : /// class be destroyed.
138 : void Shutdown();
139 :
140 : /// Returns a \em raw pointer to the underlying \a grpc_completion_queue
141 : /// instance.
142 : ///
143 : /// \warning Remember that the returned instance is owned. No transfer of
144 : /// owership is performed.
145 3948264 : grpc_completion_queue* cq() { return cq_; }
146 :
147 : private:
148 : // Friend synchronous wrappers so that they can access Pluck(), which is
149 : // a semi-private API geared towards the synchronous implementation.
150 : template <class R>
151 : friend class ::grpc::ClientReader;
152 : template <class W>
153 : friend class ::grpc::ClientWriter;
154 : template <class R, class W>
155 : friend class ::grpc::ClientReaderWriter;
156 : template <class R>
157 : friend class ::grpc::ServerReader;
158 : template <class W>
159 : friend class ::grpc::ServerWriter;
160 : template <class R, class W>
161 : friend class ::grpc::ServerReaderWriter;
162 : template <class ServiceType, class RequestType, class ResponseType>
163 : friend class RpcMethodHandler;
164 : template <class ServiceType, class RequestType, class ResponseType>
165 : friend class ClientStreamingHandler;
166 : template <class ServiceType, class RequestType, class ResponseType>
167 : friend class ServerStreamingHandler;
168 : template <class ServiceType, class RequestType, class ResponseType>
169 : friend class BidiStreamingHandler;
170 : friend class UnknownMethodHandler;
171 : friend class ::grpc::Server;
172 : friend class ::grpc::ServerContext;
173 : template <class InputMessage, class OutputMessage>
174 : friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
175 : ClientContext* context,
176 : const InputMessage& request,
177 : OutputMessage* result);
178 :
179 : NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
180 :
181 : /// Wraps \a grpc_completion_queue_pluck.
182 : /// \warning Must not be mixed with calls to \a Next.
183 : bool Pluck(CompletionQueueTag* tag);
184 :
185 : /// Performs a single polling pluck on \a tag.
186 : void TryPluck(CompletionQueueTag* tag);
187 :
188 : grpc_completion_queue* cq_; // owned
189 : };
190 :
191 : /// An interface allowing implementors to process and filter event tags.
192 11538944 : class CompletionQueueTag {
193 : public:
194 9152678 : virtual ~CompletionQueueTag() {}
195 : // Called prior to returning from Next(), return value is the status of the
196 : // operation (return status is the default thing to do). If this function
197 : // returns false, the tag is dropped and not returned from the completion
198 : // queue
199 : virtual bool FinalizeResult(void** tag, bool* status) = 0;
200 : };
201 :
202 : /// A specific type of completion queue used by the processing of notifications
203 : /// by servers. Instantiated by \a ServerBuilder.
204 86 : class ServerCompletionQueue : public CompletionQueue {
205 : private:
206 : friend class ServerBuilder;
207 43 : ServerCompletionQueue() {}
208 : };
209 :
210 : } // namespace grpc
211 :
212 : #endif // GRPCXX_COMPLETION_QUEUE_H
|