int object_stream::read(msgpack::object* obj, std::auto_ptr<msgpack::zone>* zone, double timeout_sec) { clock_time start = get_clock_time(); while(true) { if(unpacker.execute()) { *obj = unpacker.data(); zone->reset( unpacker.release_zone() ); unpacker.reset(); return 1; } unpacker.reserve_buffer(1024); ssize_t rl; while(true) { rl = ::read(iofd, unpacker.buffer(), unpacker.buffer_capacity()); if(rl > 0) break; if(rl == 0) { return -1; } if(errno == EINTR) { continue; } if(timeout_sec > 0.0 && timeout_sec < (double)(get_clock_time() - start)){ throw rpc_timeout_error("timeout"); } if(errno == EAGAIN) { continue; } return -1; } unpacker.buffer_consumed(rl); } }
void async_client::readable_callback(int fd, int events) { if (events == EV_READ) { int r = sock_->recv_async(); if (r < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { throw JUBATUS_EXCEPTION(rpc_io_error() << jubatus::exception::error_api_func("read") << jubatus::exception::error_errno(errno)); } else if (r == 0) { // closed socket sock_->disconnected(); } else { rpc_response_t res; if (sock_->salvage(res.response, res.zone)) { //cout << __FILE__ << " " << __LINE__ << ":"<< endl; //cout << "\ta0: "<< int(res.response.a0) << endl; //cout << "\ta2: "<< res.response.a2.type << " " << res.response.a2.is_nil() << " " << res.response.a2 << endl; //cout << "\ta3: "<< res.response.a3.type << " " << res.response.a3.is_nil() << " " << res.response.a3 << endl;; // Response received event_del(&context_->ev_read); // RPC Response Message: [type = 1, msgid, error, result] if (res.response.a0 == 1) results_.push_back(res); } } } else { // EV_TIMEOUT or error occured if (events == EV_TIMEOUT) throw JUBATUS_EXCEPTION(rpc_timeout_error() << jubatus::exception::error_api_func("read") << jubatus::exception::error_errno(errno)); else throw JUBATUS_EXCEPTION(rpc_internal_error() << jubatus::exception::error_api_func("read") << jubatus::exception::error_errno(errno)); } }
int object_stream::write(const void* data, size_t size, double timeout_sec) { const char* p = static_cast<const char*>(data); const char* const pend = p + size; clock_time start = get_clock_time(); while(p < pend) { ssize_t rl = ::write(iofd, p, pend-p); if(rl <= 0) { if(rl == 0) { return -1; } if(errno == EINTR) { continue; } if(timeout_sec < (double)(get_clock_time() - start)){ throw rpc_timeout_error("timeout"); } if(errno == EAGAIN) { continue; } return -1; } p += rl; } return size; }
void async_client::writable_callback(int fd, int events) { if (events == EV_WRITE) { if (sock_->is_connecting()) sock_->set_online(); int r = sock_->send_async(send_buffer_->data(), send_buffer_->size()); if (r < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) return; // write error throw JUBATUS_EXCEPTION(rpc_io_error() << jubatus::exception::error_api_func("write") << jubatus::exception::error_errno(errno)); } else if (r == 0) { // there is no effect } else if (sock_->sent_size() == send_buffer_->size()){ // current packet sending finished event_del(&context_->ev_write); sock_->reset_progress(); } } else { // EV_TIMEOUT or error occured if (events == EV_TIMEOUT) throw JUBATUS_EXCEPTION(rpc_timeout_error() << jubatus::exception::error_api_func("write") << jubatus::exception::error_errno(errno)); else throw JUBATUS_EXCEPTION(rpc_internal_error() << jubatus::exception::error_api_func("write") << jubatus::exception::error_errno(errno)); } }