mirror of
https://github.com/wassname/ray.git
synced 2026-08-12 12:20:11 +08:00
111 lines
3.1 KiB
C++
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();
|
|
}
|