commit
474b97e44e
38 changed files with 558 additions and 36 deletions
@ -0,0 +1,50 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/ext/transport/chttp2/transport/context_list.h" |
||||
|
||||
namespace { |
||||
void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr; |
||||
} |
||||
|
||||
namespace grpc_core { |
||||
void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, |
||||
grpc_error* error) { |
||||
ContextList* head = static_cast<ContextList*>(arg); |
||||
ContextList* to_be_freed; |
||||
while (head != nullptr) { |
||||
if (error == GRPC_ERROR_NONE && ts != nullptr) { |
||||
if (write_timestamps_callback_g) { |
||||
write_timestamps_callback_g(head->s_->context, ts); |
||||
} |
||||
} |
||||
GRPC_CHTTP2_STREAM_UNREF(static_cast<grpc_chttp2_stream*>(head->s_), |
||||
"timestamp"); |
||||
to_be_freed = head; |
||||
head = head->next_; |
||||
grpc_core::Delete(to_be_freed); |
||||
} |
||||
} |
||||
|
||||
void grpc_http2_set_write_timestamps_callback( |
||||
void (*fn)(void*, grpc_core::Timestamps*)) { |
||||
write_timestamps_callback_g = fn; |
||||
} |
||||
} /* namespace grpc_core */ |
@ -0,0 +1,70 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H |
||||
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/buffer_list.h" |
||||
|
||||
#include "src/core/ext/transport/chttp2/transport/internal.h" |
||||
|
||||
namespace grpc_core { |
||||
/** A list of RPC Contexts */ |
||||
class ContextList { |
||||
public: |
||||
/* Creates a new element with \a context as the value and appends it to the
|
||||
* list. */ |
||||
static void Append(ContextList** head, grpc_chttp2_stream* s) { |
||||
/* Make sure context is not already present */ |
||||
GRPC_CHTTP2_STREAM_REF(s, "timestamp"); |
||||
|
||||
#ifndef NDEBUG |
||||
ContextList* ptr = *head; |
||||
while (ptr != nullptr) { |
||||
if (ptr->s_ == s) { |
||||
GPR_ASSERT( |
||||
false && |
||||
"Trying to append a stream that is already present in the list"); |
||||
} |
||||
ptr = ptr->next_; |
||||
} |
||||
#endif |
||||
|
||||
/* Create a new element in the list and add it at the front */ |
||||
ContextList* elem = grpc_core::New<ContextList>(); |
||||
elem->s_ = s; |
||||
elem->next_ = *head; |
||||
*head = elem; |
||||
} |
||||
|
||||
/* Executes a function \a fn with each context in the list and \a ts. It also
|
||||
* frees up the entire list after this operation. */ |
||||
static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); |
||||
|
||||
private: |
||||
grpc_chttp2_stream* s_ = nullptr; |
||||
ContextList* next_ = nullptr; |
||||
}; |
||||
|
||||
void grpc_http2_set_write_timestamps_callback( |
||||
void (*fn)(void*, grpc_core::Timestamps*)); |
||||
} /* namespace grpc_core */ |
||||
|
||||
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */ |
@ -0,0 +1,98 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#include <gtest/gtest.h> |
||||
#include <new> |
||||
#include <vector> |
||||
|
||||
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" |
||||
#include "src/core/ext/transport/chttp2/transport/context_list.h" |
||||
#include "src/core/lib/transport/transport.h" |
||||
#include "test/core/util/mock_endpoint.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
namespace grpc_core { |
||||
namespace testing { |
||||
namespace { |
||||
void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) { |
||||
GPR_ASSERT(arg != nullptr); |
||||
gpr_atm* done = reinterpret_cast<gpr_atm*>(arg); |
||||
gpr_atm_rel_store(done, static_cast<gpr_atm>(1)); |
||||
} |
||||
|
||||
void discard_write(grpc_slice slice) {} |
||||
|
||||
/** Tests that all ContextList elements in the list are flushed out on
|
||||
* execute. |
||||
* Also tests that arg is passed correctly. |
||||
*/ |
||||
TEST(ContextList, ExecuteFlushesList) { |
||||
grpc_core::ContextList* list = nullptr; |
||||
grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); |
||||
const int kNumElems = 5; |
||||
grpc_core::ExecCtx exec_ctx; |
||||
grpc_stream_refcount ref; |
||||
GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "dummy ref"); |
||||
grpc_resource_quota* resource_quota = |
||||
grpc_resource_quota_create("context_list_test"); |
||||
grpc_endpoint* mock_endpoint = |
||||
grpc_mock_endpoint_create(discard_write, resource_quota); |
||||
grpc_transport* t = |
||||
grpc_create_chttp2_transport(nullptr, mock_endpoint, true); |
||||
std::vector<grpc_chttp2_stream*> s; |
||||
s.reserve(kNumElems); |
||||
gpr_atm verifier_called[kNumElems]; |
||||
for (auto i = 0; i < kNumElems; i++) { |
||||
s.push_back(static_cast<grpc_chttp2_stream*>( |
||||
gpr_malloc(grpc_transport_stream_size(t)))); |
||||
grpc_transport_init_stream(reinterpret_cast<grpc_transport*>(t), |
||||
reinterpret_cast<grpc_stream*>(s[i]), &ref, |
||||
nullptr, nullptr); |
||||
s[i]->context = &verifier_called[i]; |
||||
gpr_atm_rel_store(&verifier_called[i], static_cast<gpr_atm>(0)); |
||||
grpc_core::ContextList::Append(&list, s[i]); |
||||
} |
||||
grpc_core::Timestamps ts; |
||||
grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); |
||||
for (auto i = 0; i < kNumElems; i++) { |
||||
GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == |
||||
static_cast<gpr_atm>(1)); |
||||
grpc_transport_destroy_stream(reinterpret_cast<grpc_transport*>(t), |
||||
reinterpret_cast<grpc_stream*>(s[i]), |
||||
nullptr); |
||||
exec_ctx.Flush(); |
||||
gpr_free(s[i]); |
||||
} |
||||
grpc_transport_destroy(t); |
||||
grpc_resource_quota_unref(resource_quota); |
||||
exec_ctx.Flush(); |
||||
} |
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc_test_init(argc, argv); |
||||
grpc_init(); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
Loading…
Reference in new issue