|
|
@ -32,12 +32,8 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A completion queue implements a producer-consumer queue, with two main
|
|
|
|
/// A completion queue implements a concurrent producer-consumer queue, with two
|
|
|
|
/// methods:
|
|
|
|
/// main methods, \a Next and \a AsyncNext.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// - Next
|
|
|
|
|
|
|
|
/// - AsyncNext XXX
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
#ifndef GRPCXX_COMPLETION_QUEUE_H |
|
|
|
#ifndef GRPCXX_COMPLETION_QUEUE_H |
|
|
|
#define GRPCXX_COMPLETION_QUEUE_H |
|
|
|
#define GRPCXX_COMPLETION_QUEUE_H |
|
|
|
|
|
|
|
|
|
|
@ -81,35 +77,67 @@ class Server; |
|
|
|
class ServerBuilder; |
|
|
|
class ServerBuilder; |
|
|
|
class ServerContext; |
|
|
|
class ServerContext; |
|
|
|
|
|
|
|
|
|
|
|
// grpc_completion_queue wrapper class
|
|
|
|
// This class is a thin wrapper around \a grpc_completion_queue (see
|
|
|
|
|
|
|
|
// \a src/core/surface/completion_queue.h).
|
|
|
|
class CompletionQueue : public GrpcLibrary { |
|
|
|
class CompletionQueue : public GrpcLibrary { |
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
/// Default constructor. Implicitly creates a \a grpc_completion_queue
|
|
|
|
|
|
|
|
/// instance.
|
|
|
|
CompletionQueue(); |
|
|
|
CompletionQueue(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Wrap \a take, taking ownership of the instance.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \param take The completion queue instance to wrap. Ownership is taken.
|
|
|
|
explicit CompletionQueue(grpc_completion_queue* take); |
|
|
|
explicit CompletionQueue(grpc_completion_queue* take); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Destructor. Destroys the owned wrapped completion queue / instance.
|
|
|
|
~CompletionQueue() GRPC_OVERRIDE; |
|
|
|
~CompletionQueue() GRPC_OVERRIDE; |
|
|
|
|
|
|
|
|
|
|
|
// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT
|
|
|
|
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
|
|
|
|
enum NextStatus { SHUTDOWN, GOT_EVENT, TIMEOUT }; |
|
|
|
enum NextStatus { SHUTDOWN, GOT_EVENT, TIMEOUT }; |
|
|
|
|
|
|
|
|
|
|
|
// Nonblocking (until deadline) read from queue.
|
|
|
|
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
|
|
|
|
// Cannot rely on result of tag or ok if return is TIMEOUT
|
|
|
|
/// Both \a tag and \a ok are updated upon success (if an event is available
|
|
|
|
|
|
|
|
/// within the \a deadline). A \a tag points to an arbitrary location usually
|
|
|
|
|
|
|
|
/// employed to uniquely identify an event.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \param tag[out] Upon sucess, updated to point to the event's tag.
|
|
|
|
|
|
|
|
/// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
|
|
|
|
|
|
|
|
/// \param deadline[in] How long to block in wait for an event.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \return The type of event read.
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
|
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { |
|
|
|
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { |
|
|
|
TimePoint<T> deadline_tp(deadline); |
|
|
|
TimePoint<T> deadline_tp(deadline); |
|
|
|
return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); |
|
|
|
return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Blocking read from queue.
|
|
|
|
/// Read from the queue, blocking until an event is available or the queue is
|
|
|
|
// Returns false if the queue is ready for destruction, true if event
|
|
|
|
/// shutting down.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \param tag[out] Updated to point to the read event's tag.
|
|
|
|
|
|
|
|
/// \param ok[out] true if read a regular event, false otherwise.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \return true if read a regular event, false if the queue is shutting down.
|
|
|
|
bool Next(void** tag, bool* ok) { |
|
|
|
bool Next(void** tag, bool* ok) { |
|
|
|
return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) != |
|
|
|
return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) != |
|
|
|
SHUTDOWN); |
|
|
|
SHUTDOWN); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Shutdown has to be called, and the CompletionQueue can only be
|
|
|
|
/// Request the shutdown of the queue.
|
|
|
|
// destructed when false is returned from Next().
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \warning This method must be called at some point. Once invoked, \a Next
|
|
|
|
|
|
|
|
/// will start to return false and \a AsyncNext will return \a
|
|
|
|
|
|
|
|
/// NextStatus::SHUTDOWN. Only once either one of these methods does that
|
|
|
|
|
|
|
|
/// (that is, once the queue has been \em drained) can an instance of this
|
|
|
|
|
|
|
|
/// class be destroyed.
|
|
|
|
void Shutdown(); |
|
|
|
void Shutdown(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
|
|
|
|
|
|
|
|
/// instance.
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// \warning Remember that the returned instance is owned. No transfer of
|
|
|
|
|
|
|
|
/// owership is performed.
|
|
|
|
grpc_completion_queue* cq() { return cq_; } |
|
|
|
grpc_completion_queue* cq() { return cq_; } |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
@ -147,27 +175,29 @@ class CompletionQueue : public GrpcLibrary { |
|
|
|
|
|
|
|
|
|
|
|
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); |
|
|
|
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); |
|
|
|
|
|
|
|
|
|
|
|
// Wraps grpc_completion_queue_pluck.
|
|
|
|
/// Wraps \a grpc_completion_queue_pluck.
|
|
|
|
// Cannot be mixed with calls to Next().
|
|
|
|
/// \warning Must not be mixed with calls to \a Next.
|
|
|
|
bool Pluck(CompletionQueueTag* tag); |
|
|
|
bool Pluck(CompletionQueueTag* tag); |
|
|
|
|
|
|
|
|
|
|
|
// Does a single polling pluck on tag
|
|
|
|
/// Performs a single polling pluck on \a tag.
|
|
|
|
void TryPluck(CompletionQueueTag* tag); |
|
|
|
void TryPluck(CompletionQueueTag* tag); |
|
|
|
|
|
|
|
|
|
|
|
grpc_completion_queue* cq_; // owned
|
|
|
|
grpc_completion_queue* cq_; // owned
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// An interface allowing implementors to process and filter event tags.
|
|
|
|
class CompletionQueueTag { |
|
|
|
class CompletionQueueTag { |
|
|
|
public: |
|
|
|
public: |
|
|
|
virtual ~CompletionQueueTag() {} |
|
|
|
virtual ~CompletionQueueTag() {} |
|
|
|
// Called prior to returning from Next(), return value
|
|
|
|
// Called prior to returning from Next(), return value is the status of the
|
|
|
|
// is the status of the operation (return status is the default thing
|
|
|
|
// operation (return status is the default thing to do). If this function
|
|
|
|
// to do)
|
|
|
|
// returns false, the tag is dropped and not returned from the completion
|
|
|
|
// If this function returns false, the tag is dropped and not returned
|
|
|
|
// queue
|
|
|
|
// from the completion queue
|
|
|
|
|
|
|
|
virtual bool FinalizeResult(void** tag, bool* status) = 0; |
|
|
|
virtual bool FinalizeResult(void** tag, bool* status) = 0; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A specific type of completion queue used by the processing of notifications
|
|
|
|
|
|
|
|
/// by servers.
|
|
|
|
class ServerCompletionQueue : public CompletionQueue { |
|
|
|
class ServerCompletionQueue : public CompletionQueue { |
|
|
|
private: |
|
|
|
private: |
|
|
|
friend class ServerBuilder; |
|
|
|
friend class ServerBuilder; |
|
|
|