PollableFd: explicit sync_with_poll
GitOrigin-RevId: 71fa35a594816e84e372ebcfa9d0077a13f26a62
This commit is contained in:
parent
ceb49d0143
commit
38ef3a75cc
@ -61,15 +61,16 @@ class HelloWorld : public Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status do_loop() {
|
Status do_loop() {
|
||||||
|
sync_with_poll(socket_fd_);
|
||||||
TRY_STATUS(read_loop());
|
TRY_STATUS(read_loop());
|
||||||
TRY_STATUS(write_loop());
|
TRY_STATUS(write_loop());
|
||||||
if (can_close(socket_fd_)) {
|
if (can_close_local(socket_fd_)) {
|
||||||
return Status::Error("CLOSE");
|
return Status::Error("CLOSE");
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
Status write_loop() {
|
Status write_loop() {
|
||||||
while (can_write(socket_fd_) && write_pos_ < write_buf_.size()) {
|
while (can_write_local(socket_fd_) && write_pos_ < write_buf_.size()) {
|
||||||
TRY_RESULT(written, socket_fd_.write(Slice(write_buf_).substr(write_pos_)));
|
TRY_RESULT(written, socket_fd_.write(Slice(write_buf_).substr(write_pos_)));
|
||||||
write_pos_ += written;
|
write_pos_ += written;
|
||||||
if (write_pos_ == write_buf_.size()) {
|
if (write_pos_ == write_buf_.size()) {
|
||||||
@ -80,7 +81,7 @@ class HelloWorld : public Actor {
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
Status read_loop() {
|
Status read_loop() {
|
||||||
while (can_read(socket_fd_)) {
|
while (can_read_local(socket_fd_)) {
|
||||||
TRY_RESULT(read_size, socket_fd_.read(MutableSlice(read_buf.data(), read_buf.size())));
|
TRY_RESULT(read_size, socket_fd_.read(MutableSlice(read_buf.data(), read_buf.size())));
|
||||||
for (size_t i = 0; i < read_size; i++) {
|
for (size_t i = 0; i < read_size; i++) {
|
||||||
if (read_buf[i] == '\n') {
|
if (read_buf[i] == '\n') {
|
||||||
|
@ -55,19 +55,18 @@ class HttpEchoConnection : public Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() override {
|
void loop() override {
|
||||||
|
sync_with_poll(fd_);
|
||||||
auto status = [&] {
|
auto status = [&] {
|
||||||
TRY_STATUS(loop_read());
|
TRY_STATUS(loop_read());
|
||||||
TRY_STATUS(loop_write());
|
TRY_STATUS(loop_write());
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}();
|
}();
|
||||||
if (status.is_error() || can_close(fd_)) {
|
if (status.is_error() || can_close_local(fd_)) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status loop_read() {
|
Status loop_read() {
|
||||||
if (can_read(fd_)) {
|
|
||||||
TRY_STATUS(fd_.flush_read());
|
TRY_STATUS(fd_.flush_read());
|
||||||
}
|
|
||||||
while (true) {
|
while (true) {
|
||||||
TRY_RESULT(need, reader_.read_next(&query_));
|
TRY_RESULT(need, reader_.read_next(&query_));
|
||||||
if (need == 0) {
|
if (need == 0) {
|
||||||
|
@ -130,6 +130,7 @@ class RawConnection {
|
|||||||
if (has_error_) {
|
if (has_error_) {
|
||||||
return Status::Error("Connection has already failed");
|
return Status::Error("Connection has already failed");
|
||||||
}
|
}
|
||||||
|
sync_with_poll(socket_fd_);
|
||||||
|
|
||||||
// read/write
|
// read/write
|
||||||
// EINVAL may be returned in linux kernel < 2.6.28. And on some new kernels too.
|
// EINVAL may be returned in linux kernel < 2.6.28. And on some new kernels too.
|
||||||
@ -139,7 +140,7 @@ class RawConnection {
|
|||||||
TRY_STATUS(flush_read(auth_key, callback));
|
TRY_STATUS(flush_read(auth_key, callback));
|
||||||
TRY_STATUS(callback.before_write());
|
TRY_STATUS(callback.before_write());
|
||||||
TRY_STATUS(flush_write());
|
TRY_STATUS(flush_write());
|
||||||
if (can_close(socket_fd_)) {
|
if (can_close_local(socket_fd_)) {
|
||||||
return Status::Error("Connection closed");
|
return Status::Error("Connection closed");
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
|
@ -92,7 +92,8 @@ void HttpConnectionBase::timeout_expired() {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
void HttpConnectionBase::loop() {
|
void HttpConnectionBase::loop() {
|
||||||
if (can_read(fd_)) {
|
sync_with_poll(fd_);
|
||||||
|
if (can_read_local(fd_)) {
|
||||||
LOG(DEBUG) << "Can read from the connection";
|
LOG(DEBUG) << "Can read from the connection";
|
||||||
auto r = fd_.flush_read();
|
auto r = fd_.flush_read();
|
||||||
if (r.is_error()) {
|
if (r.is_error()) {
|
||||||
@ -133,7 +134,7 @@ void HttpConnectionBase::loop() {
|
|||||||
|
|
||||||
write_source_.wakeup();
|
write_source_.wakeup();
|
||||||
|
|
||||||
if (can_write(fd_)) {
|
if (can_write_local(fd_)) {
|
||||||
LOG(DEBUG) << "Can write to the connection";
|
LOG(DEBUG) << "Can write to the connection";
|
||||||
auto r = fd_.flush_write();
|
auto r = fd_.flush_write();
|
||||||
if (r.is_error()) {
|
if (r.is_error()) {
|
||||||
@ -146,7 +147,7 @@ void HttpConnectionBase::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Status pending_error;
|
Status pending_error;
|
||||||
if (fd_.get_poll_info().get_flags().has_pending_error()) {
|
if (fd_.get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
pending_error = fd_.get_pending_error();
|
pending_error = fd_.get_pending_error();
|
||||||
}
|
}
|
||||||
if (pending_error.is_ok() && write_sink_.status().is_error()) {
|
if (pending_error.is_ok() && write_sink_.status().is_error()) {
|
||||||
@ -163,7 +164,7 @@ void HttpConnectionBase::loop() {
|
|||||||
state_ = State::Close;
|
state_ = State::Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_close(fd_)) {
|
if (can_close_local(fd_)) {
|
||||||
LOG(DEBUG) << "Can close the connection";
|
LOG(DEBUG) << "Can close the connection";
|
||||||
state_ = State::Close;
|
state_ = State::Close;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,8 @@ void TcpListener::loop() {
|
|||||||
if (server_fd_.empty()) {
|
if (server_fd_.empty()) {
|
||||||
start_up();
|
start_up();
|
||||||
}
|
}
|
||||||
while (can_read(server_fd_)) {
|
sync_with_poll(server_fd_);
|
||||||
|
while (can_read_local(server_fd_)) {
|
||||||
auto r_socket_fd = server_fd_.accept();
|
auto r_socket_fd = server_fd_.accept();
|
||||||
if (r_socket_fd.is_error()) {
|
if (r_socket_fd.is_error()) {
|
||||||
if (r_socket_fd.error().code() != -1) {
|
if (r_socket_fd.error().code() != -1) {
|
||||||
@ -51,7 +52,7 @@ void TcpListener::loop() {
|
|||||||
send_closure(callback_, &Callback::accept, r_socket_fd.move_as_ok());
|
send_closure(callback_, &Callback::accept, r_socket_fd.move_as_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_close(server_fd_)) {
|
if (can_close_local(server_fd_)) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,12 +55,14 @@ void TransparentProxy::start_up() {
|
|||||||
VLOG(proxy) << "Begin to connect to proxy";
|
VLOG(proxy) << "Begin to connect to proxy";
|
||||||
Scheduler::subscribe(fd_.get_poll_info().extract_pollable_fd(this));
|
Scheduler::subscribe(fd_.get_poll_info().extract_pollable_fd(this));
|
||||||
set_timeout_in(10);
|
set_timeout_in(10);
|
||||||
if (can_write(fd_)) {
|
sync_with_poll(fd_);
|
||||||
|
if (can_write_local(fd_)) {
|
||||||
loop();
|
loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransparentProxy::loop() {
|
void TransparentProxy::loop() {
|
||||||
|
sync_with_poll(fd_);
|
||||||
auto status = [&] {
|
auto status = [&] {
|
||||||
TRY_STATUS(fd_.flush_read());
|
TRY_STATUS(fd_.flush_read());
|
||||||
TRY_STATUS(loop_impl());
|
TRY_STATUS(loop_impl());
|
||||||
@ -70,7 +72,7 @@ void TransparentProxy::loop() {
|
|||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
on_error(std::move(status));
|
on_error(std::move(status));
|
||||||
}
|
}
|
||||||
if (can_close(fd_)) {
|
if (can_close_local(fd_)) {
|
||||||
on_error(Status::Error("Connection closed"));
|
on_error(Status::Error("Connection closed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,15 +31,16 @@ class BufferedFdBase : public FdT {
|
|||||||
Result<size_t> flush_write() TD_WARN_UNUSED_RESULT;
|
Result<size_t> flush_write() TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
bool need_flush_write(size_t at_least = 0) {
|
bool need_flush_write(size_t at_least = 0) {
|
||||||
CHECK(write_);
|
return ready_for_flush_write() > at_least;
|
||||||
write_->sync_with_writer();
|
|
||||||
return write_->size() > at_least;
|
|
||||||
}
|
}
|
||||||
size_t ready_for_flush_write() {
|
size_t ready_for_flush_write() {
|
||||||
CHECK(write_);
|
CHECK(write_);
|
||||||
write_->sync_with_writer();
|
write_->sync_with_writer();
|
||||||
return write_->size();
|
return write_->size();
|
||||||
}
|
}
|
||||||
|
void sync_with_poll() {
|
||||||
|
::td::sync_with_poll(*this);
|
||||||
|
}
|
||||||
void set_input_writer(ChainBufferWriter *read) {
|
void set_input_writer(ChainBufferWriter *read) {
|
||||||
read_ = read;
|
read_ = read;
|
||||||
}
|
}
|
||||||
@ -99,7 +100,7 @@ template <class FdT>
|
|||||||
Result<size_t> BufferedFdBase<FdT>::flush_read(size_t max_read) {
|
Result<size_t> BufferedFdBase<FdT>::flush_read(size_t max_read) {
|
||||||
CHECK(read_);
|
CHECK(read_);
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
while (::td::can_read(*this) && max_read) {
|
while (::td::can_read_local(*this) && max_read) {
|
||||||
MutableSlice slice = read_->prepare_append().truncate(max_read);
|
MutableSlice slice = read_->prepare_append().truncate(max_read);
|
||||||
TRY_RESULT(x, FdT::read(slice));
|
TRY_RESULT(x, FdT::read(slice));
|
||||||
slice.truncate(x);
|
slice.truncate(x);
|
||||||
@ -115,7 +116,7 @@ Result<size_t> BufferedFdBase<FdT>::flush_write() {
|
|||||||
// TODO: sync on demand
|
// TODO: sync on demand
|
||||||
write_->sync_with_writer();
|
write_->sync_with_writer();
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
while (!write_->empty() && ::td::can_write(*this)) {
|
while (!write_->empty() && ::td::can_write_local(*this)) {
|
||||||
constexpr size_t BUF_SIZE = 20;
|
constexpr size_t BUF_SIZE = 20;
|
||||||
IoSlice buf[BUF_SIZE];
|
IoSlice buf[BUF_SIZE];
|
||||||
|
|
||||||
|
@ -114,8 +114,11 @@ class BufferedUdp : public UdpSocketFd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if TD_PORT_POSIX
|
#if TD_PORT_POSIX
|
||||||
|
void sync_with_poll() {
|
||||||
|
::td::sync_with_poll(*this);
|
||||||
|
}
|
||||||
Result<optional<UdpMessage>> receive() {
|
Result<optional<UdpMessage>> receive() {
|
||||||
if (input_.empty() && can_read(*this)) {
|
if (input_.empty() && can_read_local(*this)) {
|
||||||
TRY_STATUS(flush_read_once());
|
TRY_STATUS(flush_read_once());
|
||||||
}
|
}
|
||||||
if (input_.empty()) {
|
if (input_.empty()) {
|
||||||
@ -130,7 +133,7 @@ class BufferedUdp : public UdpSocketFd {
|
|||||||
|
|
||||||
Status flush_send() {
|
Status flush_send() {
|
||||||
Status status;
|
Status status;
|
||||||
while (status.is_ok() && can_write(*this) && !output_.empty()) {
|
while (status.is_ok() && can_write_local(*this) && !output_.empty()) {
|
||||||
status = flush_send_once();
|
status = flush_send_once();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
@ -263,7 +263,7 @@ class ServerSocketFdImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Status get_pending_error() {
|
Status get_pending_error() {
|
||||||
if (!get_poll_info().get_flags().has_pending_error()) {
|
if (!get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
||||||
|
@ -122,7 +122,7 @@ class SocketFdImpl : private Iocp::Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<size_t> read(MutableSlice slice) {
|
Result<size_t> read(MutableSlice slice) {
|
||||||
if (get_poll_info().get_flags().has_pending_error()) {
|
if (get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
TRY_STATUS(get_pending_error());
|
TRY_STATUS(get_pending_error());
|
||||||
}
|
}
|
||||||
input_reader_.sync_with_writer();
|
input_reader_.sync_with_writer();
|
||||||
@ -435,7 +435,7 @@ class SocketFdImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Result<size_t> read(MutableSlice slice) {
|
Result<size_t> read(MutableSlice slice) {
|
||||||
if (get_poll_info().get_flags().has_pending_error()) {
|
if (get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
TRY_STATUS(get_pending_error());
|
TRY_STATUS(get_pending_error());
|
||||||
}
|
}
|
||||||
int native_fd = get_native_fd().socket();
|
int native_fd = get_native_fd().socket();
|
||||||
@ -482,7 +482,7 @@ class SocketFdImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status get_pending_error() {
|
Status get_pending_error() {
|
||||||
if (!get_poll_info().get_flags().has_pending_error()) {
|
if (!get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "td/utils/port/detail/Iocp.h"
|
#include "td/utils/port/detail/Iocp.h"
|
||||||
#include "td/utils/port/detail/NativeFd.h"
|
#include "td/utils/port/detail/NativeFd.h"
|
||||||
#include "td/utils/port/PollFlags.h"
|
#include "td/utils/port/PollFlags.h"
|
||||||
|
#include "td/utils/port/detail/PollableFd.h"
|
||||||
#include "td/utils/port/thread.h"
|
#include "td/utils/port/thread.h"
|
||||||
#include "td/utils/ScopeGuard.h"
|
#include "td/utils/ScopeGuard.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
@ -102,7 +103,7 @@ class BufferedStdinImpl : public Iocp::Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<size_t> flush_read(size_t max_read = std::numeric_limits<size_t>::max()) TD_WARN_UNUSED_RESULT {
|
Result<size_t> flush_read(size_t max_read = std::numeric_limits<size_t>::max()) TD_WARN_UNUSED_RESULT {
|
||||||
info_.get_flags();
|
info_.sync_with_poll();
|
||||||
info_.clear_flags(PollFlags::Read());
|
info_.clear_flags(PollFlags::Read());
|
||||||
reader_.sync_with_writer();
|
reader_.sync_with_writer();
|
||||||
return reader_.size();
|
return reader_.size();
|
||||||
@ -196,7 +197,8 @@ class BufferedStdinImpl {
|
|||||||
|
|
||||||
Result<size_t> flush_read(size_t max_read = std::numeric_limits<size_t>::max()) TD_WARN_UNUSED_RESULT {
|
Result<size_t> flush_read(size_t max_read = std::numeric_limits<size_t>::max()) TD_WARN_UNUSED_RESULT {
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
while (::td::can_read(*this) && max_read) {
|
::td::sync_with_poll(*this);
|
||||||
|
while (::td::can_read_local(*this) && max_read) {
|
||||||
MutableSlice slice = writer_.prepare_append().truncate(max_read);
|
MutableSlice slice = writer_.prepare_append().truncate(max_read);
|
||||||
TRY_RESULT(x, file_fd_.read(slice));
|
TRY_RESULT(x, file_fd_.read(slice));
|
||||||
slice.truncate(x);
|
slice.truncate(x);
|
||||||
|
@ -477,7 +477,7 @@ class UdpSocketFdImpl {
|
|||||||
return info_.native_fd();
|
return info_.native_fd();
|
||||||
}
|
}
|
||||||
Status get_pending_error() {
|
Status get_pending_error() {
|
||||||
if (!get_poll_info().get_flags().has_pending_error()) {
|
if (!get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
TRY_STATUS(detail::get_socket_pending_error(get_native_fd()));
|
||||||
@ -487,7 +487,7 @@ class UdpSocketFdImpl {
|
|||||||
Status receive_message(UdpSocketFd::InboundMessage &message, bool &is_received) {
|
Status receive_message(UdpSocketFd::InboundMessage &message, bool &is_received) {
|
||||||
is_received = false;
|
is_received = false;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (get_poll_info().get_flags().has_pending_error()) {
|
if (get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
#ifdef MSG_ERRQUEUE
|
#ifdef MSG_ERRQUEUE
|
||||||
flags = MSG_ERRQUEUE;
|
flags = MSG_ERRQUEUE;
|
||||||
#else
|
#else
|
||||||
@ -679,7 +679,7 @@ class UdpSocketFdImpl {
|
|||||||
#endif
|
#endif
|
||||||
Status receive_messages_slow(MutableSpan<UdpSocketFd::InboundMessage> messages, size_t &cnt) {
|
Status receive_messages_slow(MutableSpan<UdpSocketFd::InboundMessage> messages, size_t &cnt) {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
while (cnt < messages.size() && get_poll_info().get_flags().can_read()) {
|
while (cnt < messages.size() && get_poll_info().get_flags_local().can_read()) {
|
||||||
auto &message = messages[cnt];
|
auto &message = messages[cnt];
|
||||||
CHECK(!message.data.empty());
|
CHECK(!message.data.empty());
|
||||||
bool is_received;
|
bool is_received;
|
||||||
@ -694,7 +694,7 @@ class UdpSocketFdImpl {
|
|||||||
Status receive_messages_fast(MutableSpan<UdpSocketFd::InboundMessage> messages, size_t &cnt) {
|
Status receive_messages_fast(MutableSpan<UdpSocketFd::InboundMessage> messages, size_t &cnt) {
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
if (get_poll_info().get_flags().has_pending_error()) {
|
if (get_poll_info().get_flags_local().has_pending_error()) {
|
||||||
#ifdef MSG_ERRQUEUE
|
#ifdef MSG_ERRQUEUE
|
||||||
flags = MSG_ERRQUEUE;
|
flags = MSG_ERRQUEUE;
|
||||||
#else
|
#else
|
||||||
|
@ -81,8 +81,9 @@ void EventFdBsd::release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EventFdBsd::acquire() {
|
void EventFdBsd::acquire() {
|
||||||
|
sync_with_poll(out_);
|
||||||
out_.get_poll_info().add_flags(PollFlags::Read());
|
out_.get_poll_info().add_flags(PollFlags::Read());
|
||||||
while (can_read(out_)) {
|
while (can_read_local(out_)) {
|
||||||
uint8 value[1024];
|
uint8 value[1024];
|
||||||
auto result = out_.read(MutableSlice(value, sizeof(value)));
|
auto result = out_.read(MutableSlice(value, sizeof(value)));
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
|
@ -85,7 +85,7 @@ void EventFdLinux::release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EventFdLinux::acquire() {
|
void EventFdLinux::acquire() {
|
||||||
impl_->info.get_flags();
|
impl_->info.sync_with_poll();
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
// Clear flags without EAGAIN and EWOULDBLOCK
|
// Clear flags without EAGAIN and EWOULDBLOCK
|
||||||
// Looks like it is safe thing to do with eventfd
|
// Looks like it is safe thing to do with eventfd
|
||||||
|
@ -90,7 +90,10 @@ class PollableFdInfo : private ListNode {
|
|||||||
void clear_flags(PollFlags flags) {
|
void clear_flags(PollFlags flags) {
|
||||||
flags_.clear_flags(flags);
|
flags_.clear_flags(flags);
|
||||||
}
|
}
|
||||||
PollFlags get_flags() const {
|
//PollFlags get_flags() const {
|
||||||
|
//return flags_.read_flags();
|
||||||
|
//}
|
||||||
|
PollFlags sync_with_poll() const {
|
||||||
return flags_.read_flags();
|
return flags_.read_flags();
|
||||||
}
|
}
|
||||||
PollFlags get_flags_local() const {
|
PollFlags get_flags_local() const {
|
||||||
@ -208,18 +211,23 @@ inline const NativeFd &PollableFd::native_fd() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class FdT>
|
template <class FdT>
|
||||||
bool can_read(const FdT &fd) {
|
void sync_with_poll(const FdT &fd) {
|
||||||
return fd.get_poll_info().get_flags().can_read() || fd.get_poll_info().get_flags().has_pending_error();
|
fd.get_poll_info().sync_with_poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class FdT>
|
template <class FdT>
|
||||||
bool can_write(const FdT &fd) {
|
bool can_read_local(const FdT &fd) {
|
||||||
return fd.get_poll_info().get_flags().can_write();
|
return fd.get_poll_info().get_flags_local().can_read() || fd.get_poll_info().get_flags_local().has_pending_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class FdT>
|
template <class FdT>
|
||||||
bool can_close(const FdT &fd) {
|
bool can_write_local(const FdT &fd) {
|
||||||
return fd.get_poll_info().get_flags().can_close();
|
return fd.get_poll_info().get_flags_local().can_write();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class FdT>
|
||||||
|
bool can_close_local(const FdT &fd) {
|
||||||
|
return fd.get_poll_info().get_flags_local().can_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -432,7 +432,8 @@ static void test_to_double() {
|
|||||||
|
|
||||||
TEST(Misc, to_double) {
|
TEST(Misc, to_double) {
|
||||||
test_to_double();
|
test_to_double();
|
||||||
const char *locale_name = (std::setlocale(LC_ALL, "fr-FR") == nullptr ? "" : "fr-FR");
|
const char *locale_name = (std::setlocale(LC_ALL, "fr-FR") == nullptr ? "C" : "fr-FR");
|
||||||
|
LOG(ERROR) << locale_name;
|
||||||
std::locale new_locale(locale_name);
|
std::locale new_locale(locale_name);
|
||||||
auto host_locale = std::locale::global(new_locale);
|
auto host_locale = std::locale::global(new_locale);
|
||||||
test_to_double();
|
test_to_double();
|
||||||
|
@ -287,7 +287,7 @@ TEST(Http, aes_file_encryption) {
|
|||||||
fd.set_input_writer(&input_writer);
|
fd.set_input_writer(&input_writer);
|
||||||
|
|
||||||
fd.get_poll_info().add_flags(PollFlags::Read());
|
fd.get_poll_info().add_flags(PollFlags::Read());
|
||||||
while (can_read(fd)) {
|
while (can_read_local(fd)) {
|
||||||
fd.flush_read(4096).ensure();
|
fd.flush_read(4096).ensure();
|
||||||
source.wakeup();
|
source.wakeup();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user