blob: 435a060be5a026980e0facf7919859311aeef292 [file] [log] [blame]
yangga4b6f5d2014-12-17 15:53:12 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
yangga4b6f5d2014-12-17 15:53:12 -08004 * 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
Craig Tillerc4165772015-02-11 10:51:04 -080034#include <grpc++/server_context.h>
Craig Tillerc7625b02015-02-18 15:18:58 -080035
36#include <mutex>
37
Craig Tiller01567522015-02-11 21:08:49 -080038#include <grpc++/impl/call.h>
Craig Tiller854a30c2015-02-11 11:44:10 -080039#include <grpc/grpc.h>
Craig Tiller492968f2015-02-18 13:14:03 -080040#include <grpc/support/log.h>
Craig Tiller854a30c2015-02-11 11:44:10 -080041#include "src/cpp/util/time.h"
yangga4b6f5d2014-12-17 15:53:12 -080042
Craig Tiller854a30c2015-02-11 11:44:10 -080043namespace grpc {
44
Craig Tiller492968f2015-02-18 13:14:03 -080045// CompletionOp
46
Craig Tillercf133f42015-02-26 14:05:56 -080047class ServerContext::CompletionOp GRPC_FINAL : public CallOpBuffer {
Craig Tiller492968f2015-02-18 13:14:03 -080048 public:
Craig Tillercf133f42015-02-26 14:05:56 -080049 // initial refs: one in the server context, one in the cq
50 CompletionOp() : refs_(2), finalized_(false), cancelled_(false) {
51 AddServerRecvClose(&cancelled_);
52 }
53 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
Craig Tiller492968f2015-02-18 13:14:03 -080054
55 bool CheckCancelled(CompletionQueue* cq);
56
57 void Unref();
58
59 private:
60 std::mutex mu_;
Craig Tillercf133f42015-02-26 14:05:56 -080061 int refs_;
62 bool finalized_;
63 bool cancelled_;
Craig Tiller492968f2015-02-18 13:14:03 -080064};
65
Craig Tiller492968f2015-02-18 13:14:03 -080066void ServerContext::CompletionOp::Unref() {
67 std::unique_lock<std::mutex> lock(mu_);
68 if (--refs_ == 0) {
69 lock.unlock();
70 delete this;
71 }
72}
73
74bool ServerContext::CompletionOp::CheckCancelled(CompletionQueue* cq) {
Craig Tillerd24d13d2015-02-18 15:35:32 -080075 cq->TryPluck(this);
Craig Tiller492968f2015-02-18 13:14:03 -080076 std::lock_guard<std::mutex> g(mu_);
77 return finalized_ ? cancelled_ : false;
78}
79
80bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) {
81 GPR_ASSERT(CallOpBuffer::FinalizeResult(tag, status));
82 std::unique_lock<std::mutex> lock(mu_);
83 finalized_ = true;
84 if (!*status) cancelled_ = true;
85 if (--refs_ == 0) {
86 lock.unlock();
87 delete this;
88 }
89 return false;
90}
91
92// ServerContext body
93
Craig Tillercf133f42015-02-26 14:05:56 -080094ServerContext::ServerContext()
95 : completion_op_(nullptr),
96 call_(nullptr),
Craig Tillercf133f42015-02-26 14:05:56 -080097 sent_initial_metadata_(false) {}
Craig Tillerc6453062015-02-12 17:32:57 -080098
Craig Tiller645466e2015-02-18 09:18:33 -080099ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
Craig Tiller9dcb0f82015-02-11 15:36:31 -0800100 size_t metadata_count)
Craig Tillercf133f42015-02-26 14:05:56 -0800101 : completion_op_(nullptr),
102 deadline_(Timespec2Timepoint(deadline)),
103 call_(nullptr),
Craig Tillercf133f42015-02-26 14:05:56 -0800104 sent_initial_metadata_(false) {
Craig Tiller854a30c2015-02-11 11:44:10 -0800105 for (size_t i = 0; i < metadata_count; i++) {
Craig Tiller9dcb0f82015-02-11 15:36:31 -0800106 client_metadata_.insert(std::make_pair(
107 grpc::string(metadata[i].key),
108 grpc::string(metadata[i].value,
109 metadata[i].value + metadata[i].value_length)));
Craig Tiller854a30c2015-02-11 11:44:10 -0800110 }
111}
112
Craig Tiller3d6ceb62015-02-12 14:33:54 -0800113ServerContext::~ServerContext() {
114 if (call_) {
115 grpc_call_destroy(call_);
116 }
Craig Tiller492968f2015-02-18 13:14:03 -0800117 if (completion_op_) {
118 completion_op_->Unref();
119 }
120}
121
122void ServerContext::BeginCompletionOp(Call* call) {
123 GPR_ASSERT(!completion_op_);
124 completion_op_ = new CompletionOp();
125 call->PerformOps(completion_op_);
Craig Tiller3d6ceb62015-02-12 14:33:54 -0800126}
127
Yang Gao2b7f5372015-02-18 00:45:53 -0800128void ServerContext::AddInitialMetadata(const grpc::string& key,
Craig Tiller645466e2015-02-18 09:18:33 -0800129 const grpc::string& value) {
Yang Gao2b7f5372015-02-18 00:45:53 -0800130 initial_metadata_.insert(std::make_pair(key, value));
131}
132
133void ServerContext::AddTrailingMetadata(const grpc::string& key,
Craig Tiller645466e2015-02-18 09:18:33 -0800134 const grpc::string& value) {
Yang Gao2b7f5372015-02-18 00:45:53 -0800135 trailing_metadata_.insert(std::make_pair(key, value));
136}
137
Craig Tiller854a30c2015-02-11 11:44:10 -0800138} // namespace grpc