|
|
|
@ -33,6 +33,8 @@ |
|
|
|
|
#include "src/core/lib/event_engine/tcp_socket_utils.h" |
|
|
|
|
#include "src/core/lib/event_engine/trace.h" |
|
|
|
|
#include "src/core/lib/gpr/string.h" |
|
|
|
|
#include "src/core/lib/gprpp/construct_destruct.h" |
|
|
|
|
#include "src/core/lib/gprpp/debug_location.h" |
|
|
|
|
#include "src/core/lib/gprpp/sync.h" |
|
|
|
|
#include "src/core/lib/iomgr/closure.h" |
|
|
|
|
#include "src/core/lib/iomgr/endpoint.h" |
|
|
|
@ -94,15 +96,101 @@ class EventEngineEndpointWrapper { |
|
|
|
|
grpc_endpoint* GetGrpcEndpoint() { return &eeep_->base; } |
|
|
|
|
|
|
|
|
|
// Read using the underlying EventEngine endpoint object.
|
|
|
|
|
void Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer, |
|
|
|
|
bool Read(grpc_closure* read_cb, grpc_slice_buffer* pending_read_buffer, |
|
|
|
|
const EventEngine::Endpoint::ReadArgs* args) { |
|
|
|
|
endpoint_->Read(std::move(on_read), buffer, args); |
|
|
|
|
Ref(); |
|
|
|
|
pending_read_cb_ = read_cb; |
|
|
|
|
pending_read_buffer_ = pending_read_buffer; |
|
|
|
|
// TODO(vigneshbabu): Use SliceBufferCast<> here.
|
|
|
|
|
grpc_core::Construct(reinterpret_cast<SliceBuffer*>(&eeep_->read_buffer), |
|
|
|
|
SliceBuffer::TakeCSliceBuffer(*pending_read_buffer_)); |
|
|
|
|
SliceBuffer* read_buffer = |
|
|
|
|
reinterpret_cast<SliceBuffer*>(&eeep_->read_buffer); |
|
|
|
|
read_buffer->Clear(); |
|
|
|
|
return endpoint_->Read( |
|
|
|
|
[this](absl::Status status) { FinishPendingRead(status); }, read_buffer, |
|
|
|
|
args); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FinishPendingRead(absl::Status status) { |
|
|
|
|
auto* read_buffer = reinterpret_cast<SliceBuffer*>(&eeep_->read_buffer); |
|
|
|
|
grpc_slice_buffer_move_into(read_buffer->c_slice_buffer(), |
|
|
|
|
pending_read_buffer_); |
|
|
|
|
read_buffer->~SliceBuffer(); |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
size_t i; |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p READ (peer=%s) error=%s", eeep_->wrapper, |
|
|
|
|
std::string(eeep_->wrapper->PeerAddress()).c_str(), |
|
|
|
|
status.ToString().c_str()); |
|
|
|
|
if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { |
|
|
|
|
for (i = 0; i < pending_read_buffer_->count; i++) { |
|
|
|
|
char* dump = grpc_dump_slice(pending_read_buffer_->slices[i], |
|
|
|
|
GPR_DUMP_HEX | GPR_DUMP_ASCII); |
|
|
|
|
gpr_log(GPR_DEBUG, "READ DATA: %s", dump); |
|
|
|
|
gpr_free(dump); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
pending_read_buffer_ = nullptr; |
|
|
|
|
grpc_closure* cb = pending_read_cb_; |
|
|
|
|
pending_read_cb_ = nullptr; |
|
|
|
|
if (grpc_core::ExecCtx::Get() == nullptr) { |
|
|
|
|
grpc_core::ApplicationCallbackExecCtx app_ctx; |
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} else { |
|
|
|
|
grpc_core::Closure::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} |
|
|
|
|
// For the ref taken in EventEngineEndpointWrapper::Read().
|
|
|
|
|
Unref(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Write using the underlying EventEngine endpoint object
|
|
|
|
|
void Write(absl::AnyInvocable<void(absl::Status)> on_writable, |
|
|
|
|
SliceBuffer* data, const EventEngine::Endpoint::WriteArgs* args) { |
|
|
|
|
endpoint_->Write(std::move(on_writable), data, args); |
|
|
|
|
bool Write(grpc_closure* write_cb, grpc_slice_buffer* slices, |
|
|
|
|
const EventEngine::Endpoint::WriteArgs* args) { |
|
|
|
|
Ref(); |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
size_t i; |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p WRITE (peer=%s)", this, |
|
|
|
|
std::string(PeerAddress()).c_str()); |
|
|
|
|
if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { |
|
|
|
|
for (i = 0; i < slices->count; i++) { |
|
|
|
|
char* dump = |
|
|
|
|
grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); |
|
|
|
|
gpr_log(GPR_DEBUG, "WRITE DATA: %s", dump); |
|
|
|
|
gpr_free(dump); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// TODO(vigneshbabu): Use SliceBufferCast<> here.
|
|
|
|
|
grpc_core::Construct(reinterpret_cast<SliceBuffer*>(&eeep_->write_buffer), |
|
|
|
|
SliceBuffer::TakeCSliceBuffer(*slices)); |
|
|
|
|
SliceBuffer* write_buffer = |
|
|
|
|
reinterpret_cast<SliceBuffer*>(&eeep_->write_buffer); |
|
|
|
|
pending_write_cb_ = write_cb; |
|
|
|
|
return endpoint_->Write( |
|
|
|
|
[this](absl::Status status) { FinishPendingWrite(status); }, |
|
|
|
|
write_buffer, args); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FinishPendingWrite(absl::Status status) { |
|
|
|
|
auto* write_buffer = reinterpret_cast<SliceBuffer*>(&eeep_->write_buffer); |
|
|
|
|
write_buffer->~SliceBuffer(); |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p WRITE (peer=%s) error=%s", this, |
|
|
|
|
std::string(PeerAddress()).c_str(), status.ToString().c_str()); |
|
|
|
|
} |
|
|
|
|
grpc_closure* cb = pending_write_cb_; |
|
|
|
|
pending_write_cb_ = nullptr; |
|
|
|
|
if (grpc_core::ExecCtx::Get() == nullptr) { |
|
|
|
|
grpc_core::ApplicationCallbackExecCtx app_ctx; |
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} else { |
|
|
|
|
grpc_core::Closure::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} |
|
|
|
|
// For the ref taken in EventEngineEndpointWrapper::Write().
|
|
|
|
|
Unref(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Returns true if the endpoint is not yet shutdown. In that case, it also
|
|
|
|
@ -186,6 +274,9 @@ class EventEngineEndpointWrapper { |
|
|
|
|
std::atomic<int64_t> shutdown_ref_{1}; |
|
|
|
|
absl::AnyInvocable<void(absl::StatusOr<int>)> on_release_fd_; |
|
|
|
|
grpc_core::Mutex mu_; |
|
|
|
|
grpc_closure* pending_read_cb_; |
|
|
|
|
grpc_closure* pending_write_cb_; |
|
|
|
|
grpc_slice_buffer* pending_read_buffer_; |
|
|
|
|
std::string peer_address_; |
|
|
|
|
std::string local_address_; |
|
|
|
|
int fd_{-1}; |
|
|
|
@ -204,41 +295,11 @@ void EndpointRead(grpc_endpoint* ep, grpc_slice_buffer* slices, |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
eeep->wrapper->Ref(); |
|
|
|
|
EventEngine::Endpoint::ReadArgs read_args = {min_progress_size}; |
|
|
|
|
|
|
|
|
|
// TODO(vigneshbabu): Use SliceBufferCast<> here.
|
|
|
|
|
SliceBuffer* read_buffer = new (&eeep->read_buffer) |
|
|
|
|
SliceBuffer(SliceBuffer::TakeCSliceBuffer(*slices)); |
|
|
|
|
read_buffer->Clear(); |
|
|
|
|
eeep->wrapper->Read( |
|
|
|
|
[eeep, cb, slices](absl::Status status) { |
|
|
|
|
auto* read_buffer = reinterpret_cast<SliceBuffer*>(&eeep->read_buffer); |
|
|
|
|
grpc_slice_buffer_move_into(read_buffer->c_slice_buffer(), slices); |
|
|
|
|
read_buffer->~SliceBuffer(); |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
size_t i; |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p READ (peer=%s) error=%s", eeep->wrapper, |
|
|
|
|
std::string(eeep->wrapper->PeerAddress()).c_str(), |
|
|
|
|
status.ToString().c_str()); |
|
|
|
|
if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { |
|
|
|
|
for (i = 0; i < slices->count; i++) { |
|
|
|
|
char* dump = grpc_dump_slice(slices->slices[i], |
|
|
|
|
GPR_DUMP_HEX | GPR_DUMP_ASCII); |
|
|
|
|
gpr_log(GPR_DEBUG, "READ DATA: %s", dump); |
|
|
|
|
gpr_free(dump); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
grpc_core::ApplicationCallbackExecCtx app_ctx; |
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} |
|
|
|
|
// For the ref taken in EndpointRead
|
|
|
|
|
eeep->wrapper->Unref(); |
|
|
|
|
}, |
|
|
|
|
read_buffer, &read_args); |
|
|
|
|
if (eeep->wrapper->Read(cb, slices, &read_args)) { |
|
|
|
|
// Read succeeded immediately. Run the callback inline.
|
|
|
|
|
eeep->wrapper->FinishPendingRead(absl::OkStatus()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
eeep->wrapper->ShutdownUnref(); |
|
|
|
|
} |
|
|
|
@ -256,45 +317,11 @@ void EndpointWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
eeep->wrapper->Ref(); |
|
|
|
|
EventEngine::Endpoint::WriteArgs write_args = {arg, max_frame_size}; |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
size_t i; |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p WRITE (peer=%s)", eeep->wrapper, |
|
|
|
|
std::string(eeep->wrapper->PeerAddress()).c_str()); |
|
|
|
|
if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { |
|
|
|
|
for (i = 0; i < slices->count; i++) { |
|
|
|
|
char* dump = |
|
|
|
|
grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); |
|
|
|
|
gpr_log(GPR_DEBUG, "WRITE DATA: %s", dump); |
|
|
|
|
gpr_free(dump); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (eeep->wrapper->Write(cb, slices, &write_args)) { |
|
|
|
|
// Write succeeded immediately. Run the callback inline.
|
|
|
|
|
eeep->wrapper->FinishPendingWrite(absl::OkStatus()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(vigneshbabu): Use SliceBufferCast<> here.
|
|
|
|
|
SliceBuffer* write_buffer = new (&eeep->write_buffer) |
|
|
|
|
SliceBuffer(SliceBuffer::TakeCSliceBuffer(*slices)); |
|
|
|
|
eeep->wrapper->Write( |
|
|
|
|
[eeep, cb](absl::Status status) { |
|
|
|
|
auto* write_buffer = |
|
|
|
|
reinterpret_cast<SliceBuffer*>(&eeep->write_buffer); |
|
|
|
|
write_buffer->~SliceBuffer(); |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { |
|
|
|
|
gpr_log(GPR_INFO, "TCP: %p WRITE (peer=%s) error=%s", eeep->wrapper, |
|
|
|
|
std::string(eeep->wrapper->PeerAddress()).c_str(), |
|
|
|
|
status.ToString().c_str()); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
grpc_core::ApplicationCallbackExecCtx app_ctx; |
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, status); |
|
|
|
|
} |
|
|
|
|
// For the ref taken in EndpointWrite
|
|
|
|
|
eeep->wrapper->Unref(); |
|
|
|
|
}, |
|
|
|
|
write_buffer, &write_args); |
|
|
|
|
|
|
|
|
|
eeep->wrapper->ShutdownUnref(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|