Files
ray/src/ray/gcs/asio.cc
T

111 lines
3.1 KiB
C++

#include "asio.h"
#include "ray/util/logging.h"
RedisAsioClient::RedisAsioClient(boost::asio::io_service &io_service,
redisAsyncContext *async_context)
: async_context_(async_context),
socket_(io_service),
read_requested_(false),
write_requested_(false),
read_in_progress_(false),
write_in_progress_(false) {
// gives access to c->fd
redisContext *c = &(async_context->c);
// hiredis is already connected
// use the existing native socket
socket_.assign(boost::asio::ip::tcp::v4(), c->fd);
// register hooks with the hiredis async context
async_context->ev.addRead = call_C_addRead;
async_context->ev.delRead = call_C_delRead;
async_context->ev.addWrite = call_C_addWrite;
async_context->ev.delWrite = call_C_delWrite;
async_context->ev.cleanup = call_C_cleanup;
// C wrapper functions will use this pointer to call class members.
async_context->ev.data = this;
}
void RedisAsioClient::operate() {
if (read_requested_ && !read_in_progress_) {
read_in_progress_ = true;
socket_.async_read_some(boost::asio::null_buffers(),
boost::bind(&RedisAsioClient::handle_read, this,
boost::asio::placeholders::error));
}
if (write_requested_ && !write_in_progress_) {
write_in_progress_ = true;
socket_.async_write_some(boost::asio::null_buffers(),
boost::bind(&RedisAsioClient::handle_write, this,
boost::asio::placeholders::error));
}
}
void RedisAsioClient::handle_read(boost::system::error_code error_code) {
RAY_CHECK(!error_code || error_code == boost::asio::error::would_block);
read_in_progress_ = false;
redisAsyncHandleRead(async_context_);
if (error_code == boost::asio::error::would_block) {
operate();
}
}
void RedisAsioClient::handle_write(boost::system::error_code error_code) {
RAY_CHECK(!error_code || error_code == boost::asio::error::would_block);
write_in_progress_ = false;
redisAsyncHandleWrite(async_context_);
if (error_code == boost::asio::error::would_block) {
operate();
}
}
void RedisAsioClient::add_read() {
read_requested_ = true;
operate();
}
void RedisAsioClient::del_read() {
read_requested_ = false;
}
void RedisAsioClient::add_write() {
write_requested_ = true;
operate();
}
void RedisAsioClient::del_write() {
write_requested_ = false;
}
void RedisAsioClient::cleanup() {}
static inline RedisAsioClient *cast_to_client(void *private_data) {
RAY_CHECK(private_data != nullptr);
return static_cast<RedisAsioClient *>(private_data);
}
extern "C" void call_C_addRead(void *private_data) {
cast_to_client(private_data)->add_read();
}
extern "C" void call_C_delRead(void *private_data) {
cast_to_client(private_data)->del_read();
}
extern "C" void call_C_addWrite(void *private_data) {
cast_to_client(private_data)->add_write();
}
extern "C" void call_C_delWrite(void *private_data) {
cast_to_client(private_data)->del_write();
}
extern "C" void call_C_cleanup(void *private_data) {
cast_to_client(private_data)->cleanup();
}