A lot of fixes.
GitOrigin-RevId: c7c16991da51e09a685537a444385852e8e93af4
This commit is contained in:
parent
cfcc08ebb7
commit
fd90bf435e
@ -12,7 +12,7 @@
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/BufferedFd.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "td/net/HttpReader.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "td/mtproto/utils.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/BufferedFd.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Named.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "td/utils/ByteFlow.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/MpscPollableQueue.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/Poll.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
|
||||
|
@ -26,9 +26,10 @@
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/signals.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/port/StdStreams.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "td/utils/MimeType.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/PathView.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "td/utils/MpscPollableQueue.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
#include "td/utils/port/detail/WineventPoll.h"
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace td {
|
||||
@ -24,19 +28,18 @@ void ConcurrentScheduler::init(int32 threads_n) {
|
||||
#endif
|
||||
threads_n++;
|
||||
std::vector<std::shared_ptr<MpscPollableQueue<EventFull>>> outbound(threads_n);
|
||||
#if !TD_THREAD_UNSUPPORTED && !TD_EVENTFD_UNSUPPORTED
|
||||
for (int32 i = 0; i < threads_n; i++) {
|
||||
#if TD_THREAD_UNSUPPORTED || TD_EVENTFD_UNSUPPORTED
|
||||
#else
|
||||
auto queue = std::make_shared<MpscPollableQueue<EventFull>>();
|
||||
queue->init();
|
||||
outbound[i] = queue;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// +1 for extra scheduler for IOCP and send_closure from unrelated threads
|
||||
// It will know about other schedulers
|
||||
// Other schedulers will have no idea about its existance
|
||||
int extra_scheduler = 1;
|
||||
// Other schedulers will have no idea about its existence
|
||||
int32 extra_scheduler = 1;
|
||||
#if TD_THREAD_UNSUPPORTED || TD_EVENTFD_UNSUPPORTED
|
||||
extra_scheduler = 0;
|
||||
#endif
|
||||
@ -46,11 +49,13 @@ void ConcurrentScheduler::init(int32 threads_n) {
|
||||
auto &sched = schedulers_[i];
|
||||
sched = make_unique<Scheduler>();
|
||||
|
||||
#if !TD_THREAD_UNSUPPORTED && !TD_EVENTFD_UNSUPPORTED
|
||||
if (i >= threads_n) {
|
||||
auto queue = std::make_shared<MpscPollableQueue<EventFull>>();
|
||||
queue->init();
|
||||
outbound.push_back(std::move(queue));
|
||||
}
|
||||
#endif
|
||||
|
||||
sched->init(i, outbound, static_cast<Scheduler::Callback *>(this));
|
||||
}
|
||||
@ -88,12 +93,12 @@ void ConcurrentScheduler::start() {
|
||||
}
|
||||
}));
|
||||
}
|
||||
#endif
|
||||
#if TD_PORT_WINDOWS
|
||||
iocp_thread_ = td::thread([this] {
|
||||
iocp_thread_ = td::thread([this] {
|
||||
auto guard = this->get_send_guard();
|
||||
this->iocp_->loop();
|
||||
this->iocp_->loop();
|
||||
});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
state_ = State::Run;
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include "td/utils/MovableValue.h"
|
||||
#include "td/utils/MpscPollableQueue.h"
|
||||
#include "td/utils/ObjectPool.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/EventFd.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/Poll.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/MpscPollableQueue.h"
|
||||
#include "td/utils/ObjectPool.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <atomic>
|
||||
@ -190,10 +190,8 @@ inline void Scheduler::inc_wait_generation() {
|
||||
|
||||
template <ActorSendType send_type, class RunFuncT, class EventFuncT>
|
||||
void Scheduler::send_impl(const ActorId<> &actor_id, const RunFuncT &run_func, const EventFuncT &event_func) {
|
||||
//CHECK(has_guard_ || );
|
||||
ActorInfo *actor_info = actor_id.get_actor_info();
|
||||
if (unlikely(actor_info == nullptr || close_flag_)) {
|
||||
// LOG(ERROR) << "Invalid actor id";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,12 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Observer.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
REGISTER_TESTS(actors_simple)
|
||||
@ -621,6 +623,7 @@ TEST(Actors, always_wait_for_mailbox) {
|
||||
scheduler.finish();
|
||||
}
|
||||
|
||||
#if !TD_THREAD_UNSUPPORTED && !TD_EVENTFD_UNSUPPORTED
|
||||
TEST(Actors, send_from_other_threads) {
|
||||
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(ERROR));
|
||||
ConcurrentScheduler scheduler;
|
||||
@ -628,7 +631,7 @@ TEST(Actors, send_from_other_threads) {
|
||||
int thread_n = 10;
|
||||
class Listener : public Actor {
|
||||
public:
|
||||
Listener(int cnt) : cnt_(cnt) {
|
||||
explicit Listener(int cnt) : cnt_(cnt) {
|
||||
}
|
||||
void dec() {
|
||||
if (--cnt_ == 0) {
|
||||
@ -656,3 +659,4 @@ TEST(Actors, send_from_other_threads) {
|
||||
}
|
||||
scheduler.finish();
|
||||
}
|
||||
#endif
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Clocks.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/Random.h"
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
namespace td {
|
||||
namespace detail {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "td/net/TcpListener.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
namespace td {
|
||||
// TcpListener implementation
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "td/net/TransparentProxy.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -44,6 +44,7 @@ set(TDUTILS_SOURCE
|
||||
td/utils/port/Stat.cpp
|
||||
td/utils/port/StdStreams.cpp
|
||||
td/utils/port/thread_local.cpp
|
||||
td/utils/port/UdpSocketFd.cpp
|
||||
td/utils/port/wstring_convert.cpp
|
||||
|
||||
td/utils/port/detail/Epoll.cpp
|
||||
@ -51,11 +52,11 @@ set(TDUTILS_SOURCE
|
||||
td/utils/port/detail/EventFdLinux.cpp
|
||||
td/utils/port/detail/EventFdWindows.cpp
|
||||
td/utils/port/detail/KQueue.cpp
|
||||
td/utils/port/detail/NativeFd.cpp
|
||||
td/utils/port/detail/Poll.cpp
|
||||
td/utils/port/detail/PollableFd.cpp
|
||||
td/utils/port/detail/Select.cpp
|
||||
td/utils/port/detail/ThreadIdGuard.cpp
|
||||
td/utils/port/UdpSocketFd.cpp
|
||||
td/utils/port/detail/WineventPoll.cpp
|
||||
|
||||
${TDMIME_AUTO}
|
||||
@ -117,7 +118,6 @@ set(TDUTILS_SOURCE
|
||||
td/utils/port/detail/EventFdWindows.h
|
||||
td/utils/port/detail/KQueue.h
|
||||
td/utils/port/detail/NativeFd.h
|
||||
td/utils/port/detail/NativeFd.cpp
|
||||
td/utils/port/detail/Poll.h
|
||||
td/utils/port/detail/PollableFd.h
|
||||
td/utils/port/detail/Select.h
|
||||
@ -131,9 +131,9 @@ set(TDUTILS_SOURCE
|
||||
td/utils/benchmark.h
|
||||
td/utils/BigNum.h
|
||||
td/utils/buffer.h
|
||||
td/utils/BufferedUdp.h
|
||||
td/utils/BufferedFd.h
|
||||
td/utils/BufferedReader.h
|
||||
td/utils/BufferedUdp.h
|
||||
td/utils/ByteFlow.h
|
||||
td/utils/ChangesProcessor.h
|
||||
td/utils/Closure.h
|
||||
@ -141,8 +141,9 @@ set(TDUTILS_SOURCE
|
||||
td/utils/Container.h
|
||||
td/utils/Context.h
|
||||
td/utils/crypto.h
|
||||
td/utils/Enumerator.h
|
||||
td/utils/DecTree.h
|
||||
td/utils/Destructor.h
|
||||
td/utils/Enumerator.h
|
||||
td/utils/FileLog.h
|
||||
td/utils/filesystem.h
|
||||
td/utils/find_boundary.h
|
||||
@ -209,12 +210,12 @@ set(TDUTILS_TEST_SOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/buffer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/crypto.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/Enumerator.cpp
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/test/filesystem.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/filesystem.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/gzip.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/HazardPointers.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/heap.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/json.cpp
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/test/misc.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/misc.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/MpmcQueue.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/MpmcWaiter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/MpscLinkQueue.cpp
|
||||
|
@ -6,8 +6,12 @@
|
||||
//
|
||||
#include "td/utils/BufferedUdp.h"
|
||||
|
||||
char disable_linker_warning_about_empty_file_buffered_udp_cpp TD_UNUSED;
|
||||
|
||||
namespace td {
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
TD_THREAD_LOCAL detail::UdpReader* BufferedUdp::udp_reader_;
|
||||
TD_THREAD_LOCAL detail::UdpReader *BufferedUdp::udp_reader_;
|
||||
#endif
|
||||
|
||||
} // namespace td
|
||||
|
@ -5,21 +5,27 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
#include "td/utils/port/UdpSocketFd.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/optional.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
#include "td/utils/port/UdpSocketFd.h"
|
||||
#include "td/utils/Span.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace td {
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
namespace detail {
|
||||
class UdpWriter {
|
||||
public:
|
||||
static Status write_once(UdpSocketFd& fd, VectorQueue<UdpMessage>& queue) TD_WARN_UNUSED_RESULT {
|
||||
static Status write_once(UdpSocketFd &fd, VectorQueue<UdpMessage> &queue) TD_WARN_UNUSED_RESULT {
|
||||
std::array<UdpSocketFd::OutboundMessage, 16> messages;
|
||||
auto to_send = queue.as_span();
|
||||
size_t to_send_n = std::min(messages.size(), to_send.size());
|
||||
size_t to_send_n = td::min(messages.size(), to_send.size());
|
||||
to_send.truncate(to_send_n);
|
||||
for (size_t i = 0; i < to_send_n; i++) {
|
||||
messages[i].to = &to_send[i].address;
|
||||
@ -35,7 +41,7 @@ class UdpWriter {
|
||||
|
||||
class UdpReaderHelper {
|
||||
public:
|
||||
void init_inbound_message(UdpSocketFd::InboundMessage& message) {
|
||||
void init_inbound_message(UdpSocketFd::InboundMessage &message) {
|
||||
message.from = &message_.address;
|
||||
message.error = &message_.error;
|
||||
if (buffer_.size() < MAX_PACKET_SIZE) {
|
||||
@ -45,7 +51,7 @@ class UdpReaderHelper {
|
||||
message.data = buffer_.as_slice().truncate(MAX_PACKET_SIZE);
|
||||
}
|
||||
|
||||
UdpMessage extract_udp_message(UdpSocketFd::InboundMessage& message) {
|
||||
UdpMessage extract_udp_message(UdpSocketFd::InboundMessage &message) {
|
||||
message_.data = buffer_.from_slice(message.data);
|
||||
auto size = message_.data.size();
|
||||
size = (size + 7) & ~7;
|
||||
@ -60,7 +66,7 @@ class UdpReaderHelper {
|
||||
BufferSlice buffer_;
|
||||
};
|
||||
|
||||
//One for thread is enough
|
||||
// One for thread is enough
|
||||
class UdpReader {
|
||||
public:
|
||||
UdpReader() {
|
||||
@ -68,7 +74,7 @@ class UdpReader {
|
||||
helpers_[i].init_inbound_message(messages_[i]);
|
||||
}
|
||||
}
|
||||
Status read_once(UdpSocketFd& fd, VectorQueue<UdpMessage>& queue) TD_WARN_UNUSED_RESULT {
|
||||
Status read_once(UdpSocketFd &fd, VectorQueue<UdpMessage> &queue) TD_WARN_UNUSED_RESULT {
|
||||
for (size_t i = 0; i < messages_.size(); i++) {
|
||||
CHECK(messages_[i].data.size() == 2048);
|
||||
}
|
||||
@ -81,7 +87,6 @@ class UdpReader {
|
||||
for (size_t i = cnt; i < messages_.size(); i++) {
|
||||
CHECK(messages_[i].data.size() == 2048)
|
||||
<< " cnt = " << cnt << " i = " << i << " size = " << messages_[i].data.size() << " status = " << status;
|
||||
;
|
||||
}
|
||||
if (status.is_error() && !UdpSocketFd::is_critical_read_error(status)) {
|
||||
queue.push(UdpMessage{{}, {}, std::move(status)});
|
||||
@ -101,7 +106,7 @@ class UdpReader {
|
||||
|
||||
class BufferedUdp : public UdpSocketFd {
|
||||
public:
|
||||
BufferedUdp(UdpSocketFd fd) : UdpSocketFd(std::move(fd)) {
|
||||
explicit BufferedUdp(UdpSocketFd fd) : UdpSocketFd(std::move(fd)) {
|
||||
}
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
@ -132,8 +137,8 @@ class BufferedUdp : public UdpSocketFd {
|
||||
return std::move(as_fd());
|
||||
}
|
||||
|
||||
UdpSocketFd& as_fd() {
|
||||
return *static_cast<UdpSocketFd*>(this);
|
||||
UdpSocketFd &as_fd() {
|
||||
return *static_cast<UdpSocketFd *>(this);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -141,10 +146,10 @@ class BufferedUdp : public UdpSocketFd {
|
||||
VectorQueue<UdpMessage> input_;
|
||||
VectorQueue<UdpMessage> output_;
|
||||
|
||||
VectorQueue<UdpMessage>& input() {
|
||||
VectorQueue<UdpMessage> &input() {
|
||||
return input_;
|
||||
}
|
||||
VectorQueue<UdpMessage>& output() {
|
||||
VectorQueue<UdpMessage> &output() {
|
||||
return output_;
|
||||
}
|
||||
|
||||
@ -157,7 +162,8 @@ class BufferedUdp : public UdpSocketFd {
|
||||
return udp_reader_->read_once(as_fd(), input_);
|
||||
}
|
||||
|
||||
static TD_THREAD_LOCAL detail::UdpReader* udp_reader_;
|
||||
static TD_THREAD_LOCAL detail::UdpReader *udp_reader_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace td
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "td/utils/port/thread_local.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
template <class Impl>
|
||||
class Context {
|
||||
public:
|
||||
|
@ -6,17 +6,17 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/int_types.h"
|
||||
#include "td/utils/Random.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "int_types.h"
|
||||
#include "Random.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
template <typename KeyType, typename ValueType, typename Compare = std::less<KeyType>>
|
||||
class DecTree {
|
||||
private:
|
||||
struct Node {
|
||||
std::unique_ptr<Node> left_;
|
||||
std::unique_ptr<Node> right_;
|
||||
@ -35,15 +35,16 @@ class DecTree {
|
||||
}
|
||||
}
|
||||
|
||||
Node(KeyType key, ValueType value, uint32 y) : key_(std::move(key)), value_(std::move(value)), y_(y) {
|
||||
size_ = 1;
|
||||
Node(KeyType key, ValueType value, uint32 y) : size_(1), key_(std::move(key)), value_(std::move(value)), y_(y) {
|
||||
}
|
||||
};
|
||||
std::unique_ptr<Node> root_;
|
||||
std::unique_ptr<Node> create_node(KeyType key, ValueType value, uint32 y) {
|
||||
|
||||
static std::unique_ptr<Node> create_node(KeyType key, ValueType value, uint32 y) {
|
||||
return std::make_unique<Node>(std::move(key), std::move(value), y);
|
||||
}
|
||||
std::unique_ptr<Node> insert_node(std::unique_ptr<Node> Tree, KeyType key, ValueType value, uint32 y) {
|
||||
|
||||
static std::unique_ptr<Node> insert_node(std::unique_ptr<Node> Tree, KeyType key, ValueType value, uint32 y) {
|
||||
if (Tree == nullptr) {
|
||||
return create_node(std::move(key), std::move(value), y);
|
||||
}
|
||||
@ -63,9 +64,10 @@ class DecTree {
|
||||
// ?? assert
|
||||
}
|
||||
Tree->relax();
|
||||
return std::move(Tree);
|
||||
return Tree;
|
||||
}
|
||||
std::unique_ptr<Node> remove_node(std::unique_ptr<Node> Tree, KeyType &key) {
|
||||
|
||||
static std::unique_ptr<Node> remove_node(std::unique_ptr<Node> Tree, const KeyType &key) {
|
||||
if (Tree == nullptr) {
|
||||
// ?? assert
|
||||
return nullptr;
|
||||
@ -80,10 +82,10 @@ class DecTree {
|
||||
if (Tree != nullptr) {
|
||||
Tree->relax();
|
||||
}
|
||||
return std::move(Tree);
|
||||
return Tree;
|
||||
}
|
||||
|
||||
ValueType *get_node(std::unique_ptr<Node> &Tree, KeyType &key) {
|
||||
static ValueType *get_node(std::unique_ptr<Node> &Tree, const KeyType &key) {
|
||||
if (Tree == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -95,7 +97,8 @@ class DecTree {
|
||||
return &Tree->value_;
|
||||
}
|
||||
}
|
||||
ValueType *get_node_by_idx(std::unique_ptr<Node> &Tree, size_t idx) {
|
||||
|
||||
static ValueType *get_node_by_idx(std::unique_ptr<Node> &Tree, size_t idx) {
|
||||
CHECK(Tree != nullptr);
|
||||
auto s = (Tree->left_ != nullptr) ? Tree->left_->size_ : 0;
|
||||
if (idx < s) {
|
||||
@ -106,46 +109,46 @@ class DecTree {
|
||||
return get_node_by_idx(Tree->right_, idx - s - 1);
|
||||
}
|
||||
}
|
||||
std::pair<std::unique_ptr<Node>, std::unique_ptr<Node>> split_node(std::unique_ptr<Node> Tree, KeyType &key) {
|
||||
|
||||
static std::pair<std::unique_ptr<Node>, std::unique_ptr<Node>> split_node(std::unique_ptr<Node> Tree,
|
||||
const KeyType &key) {
|
||||
if (Tree == nullptr) {
|
||||
return std::pair<std::unique_ptr<Node>, std::unique_ptr<Node>>(nullptr, nullptr);
|
||||
return {nullptr, nullptr};
|
||||
}
|
||||
if (Compare()(key, Tree->key_)) {
|
||||
auto P = split_node(std::move(Tree->left_), key);
|
||||
Tree->left_ = std::move(P.second);
|
||||
Tree->relax();
|
||||
P.second = std::move(Tree);
|
||||
return std::move(P);
|
||||
return P;
|
||||
} else {
|
||||
auto P = split_node(std::move(Tree->right_), key);
|
||||
Tree->right_ = std::move(P.first);
|
||||
Tree->relax();
|
||||
P.first = std::move(Tree);
|
||||
return std::move(P);
|
||||
return P;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<Node> merge_node(std::unique_ptr<Node> left, std::unique_ptr<Node> right) {
|
||||
|
||||
static std::unique_ptr<Node> merge_node(std::unique_ptr<Node> left, std::unique_ptr<Node> right) {
|
||||
if (left == nullptr) {
|
||||
return std::move(right);
|
||||
return right;
|
||||
}
|
||||
if (right == nullptr) {
|
||||
return std::move(left);
|
||||
return left;
|
||||
}
|
||||
if (left->y_ < right->y_) {
|
||||
right->left_ = merge_node(std::move(left), std::move(right->left_));
|
||||
right->relax();
|
||||
return std::move(right);
|
||||
return right;
|
||||
} else {
|
||||
left->right_ = merge_node(std::move(left->right_), std::move(right));
|
||||
left->relax();
|
||||
return std::move(left);
|
||||
return left;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
DecTree() {
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
if (root_ == nullptr) {
|
||||
return 0;
|
||||
@ -156,10 +159,10 @@ class DecTree {
|
||||
void insert(KeyType key, ValueType value) {
|
||||
root_ = insert_node(std::move(root_), std::move(key), std::move(value), td::Random::fast_uint32());
|
||||
}
|
||||
void remove(KeyType &key) {
|
||||
void remove(const KeyType &key) {
|
||||
root_ = remove_node(std::move(root_), key);
|
||||
}
|
||||
ValueType *get(KeyType &key) {
|
||||
ValueType *get(const KeyType &key) {
|
||||
return get_node(root_, key);
|
||||
}
|
||||
ValueType *get_random() {
|
||||
@ -169,7 +172,7 @@ class DecTree {
|
||||
return get_node_by_idx(root_, td::Random::fast_uint32() % size());
|
||||
}
|
||||
}
|
||||
bool exists(KeyType &key) {
|
||||
bool exists(const KeyType &key) const {
|
||||
return get_node(root_, key) != nullptr;
|
||||
}
|
||||
};
|
||||
|
@ -4,8 +4,13 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/common.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
class Destructor {
|
||||
@ -43,4 +48,5 @@ template <class F>
|
||||
auto create_shared_destructor(F &&f) {
|
||||
return std::make_shared<LambdaDestructor<F>>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/StdStreams.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <limits>
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "td/utils/port/EventFd.h"
|
||||
|
||||
#if !TD_EVENTFD_UNSUPPORTED
|
||||
|
||||
#include "td/utils/SpinLock.h"
|
||||
|
||||
#if !TD_WINDOWS
|
||||
#include <poll.h>
|
||||
#include <sched.h>
|
||||
@ -17,8 +20,6 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "td/utils/SpinLock.h"
|
||||
|
||||
namespace td {
|
||||
// interface like in PollableQueue
|
||||
template <class T>
|
||||
|
@ -92,7 +92,7 @@ uint32 Random::fast_uint32() {
|
||||
if (!gen) {
|
||||
auto &rg = rand_device_helper;
|
||||
std::seed_seq seq{rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg()};
|
||||
init_thread_local<std::mt19937>(gen);
|
||||
init_thread_local<std::mt19937>(gen, seq);
|
||||
}
|
||||
return static_cast<uint32>((*gen)());
|
||||
}
|
||||
@ -102,7 +102,7 @@ uint64 Random::fast_uint64() {
|
||||
if (!gen) {
|
||||
auto &rg = rand_device_helper;
|
||||
std::seed_seq seq{rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg(), rg()};
|
||||
init_thread_local<std::mt19937_64>(gen);
|
||||
init_thread_local<std::mt19937_64>(gen, seq);
|
||||
}
|
||||
return static_cast<uint64>((*gen)());
|
||||
}
|
||||
@ -116,12 +116,13 @@ int Random::fast(int min, int max) {
|
||||
return static_cast<int>(min + fast_uint32() % (max - min + 1)); // TODO signed_cast
|
||||
}
|
||||
|
||||
Random::Xorshift128plus::Xorshift128plus(uint32 seed) {
|
||||
Random::Xorshift128plus::Xorshift128plus(uint64 seed) {
|
||||
auto next = [&]() {
|
||||
// splitmix64
|
||||
uint64_t z = (seed += UINT64_C(0x9E3779B97F4A7C15));
|
||||
z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB);
|
||||
seed += static_cast<uint64>(0x9E3779B97F4A7C15);
|
||||
uint64 z = seed;
|
||||
z = (z ^ (z >> 30)) * static_cast<uint64>(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * static_cast<uint64>(0x94D049BB133111EB);
|
||||
return z ^ (z >> 31);
|
||||
};
|
||||
seed_[0] = next();
|
||||
@ -134,11 +135,11 @@ Random::Xorshift128plus::Xorshift128plus(uint64 seed_a, uint64 seed_b) {
|
||||
}
|
||||
|
||||
uint64 Random::Xorshift128plus::operator()() {
|
||||
uint64_t x = seed_[0];
|
||||
uint64_t const y = seed_[1];
|
||||
uint64 x = seed_[0];
|
||||
const uint64 y = seed_[1];
|
||||
seed_[0] = y;
|
||||
x ^= x << 23; // a
|
||||
seed_[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
|
||||
x ^= x << 23;
|
||||
seed_[1] = x ^ y ^ (x >> 17) ^ (y >> 26);
|
||||
return seed_[1] + y;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ class Random {
|
||||
|
||||
class Xorshift128plus {
|
||||
public:
|
||||
Xorshift128plus(uint32 seed);
|
||||
explicit Xorshift128plus(uint64 seed);
|
||||
Xorshift128plus(uint64 seed_a, uint64 seed_b);
|
||||
uint64 operator()();
|
||||
|
||||
|
@ -38,7 +38,9 @@ class AtomicRefCnt {
|
||||
};
|
||||
|
||||
template <class DataT, class DeleterT>
|
||||
class SharedPtrRaw : public DeleterT, private MpscLinkQueueImpl::Node {
|
||||
class SharedPtrRaw
|
||||
: public DeleterT
|
||||
, private MpscLinkQueueImpl::Node {
|
||||
public:
|
||||
explicit SharedPtrRaw(DeleterT deleter) : DeleterT(std::move(deleter)), ref_cnt_{0}, option_magic_(Magic) {
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ inline bool operator!=(const Slice &a, const Slice &b) {
|
||||
}
|
||||
|
||||
inline bool operator<(const Slice &a, const Slice &b) {
|
||||
auto x = std::memcmp(a.data(), b.data(), std::min(a.size(), b.size()));
|
||||
auto x = std::memcmp(a.data(), b.data(), td::min(a.size(), b.size()));
|
||||
if (x == 0) {
|
||||
return a.size() < b.size();
|
||||
}
|
||||
|
@ -5,13 +5,17 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace td {
|
||||
|
||||
namespace detail {
|
||||
template <class T, class InnerT>
|
||||
class SpanImpl {
|
||||
private:
|
||||
InnerT *data_{nullptr};
|
||||
size_t size_{0};
|
||||
|
||||
@ -21,8 +25,6 @@ class SpanImpl {
|
||||
}
|
||||
SpanImpl(InnerT &data) : SpanImpl(&data, 1) {
|
||||
}
|
||||
SpanImpl(const SpanImpl &other) = default;
|
||||
SpanImpl &operator=(const SpanImpl &other) = default;
|
||||
|
||||
template <class OtherInnerT>
|
||||
SpanImpl(const SpanImpl<T, OtherInnerT> &other) : SpanImpl(other.data(), other.size()) {
|
||||
@ -34,9 +36,9 @@ class SpanImpl {
|
||||
template <size_t N>
|
||||
SpanImpl(std::array<T, N> &arr) : SpanImpl(arr.data(), arr.size()) {
|
||||
}
|
||||
SpanImpl(const std::vector<T> &v) : SpanImpl(v.data(), v.size()) {
|
||||
SpanImpl(const vector<T> &v) : SpanImpl(v.data(), v.size()) {
|
||||
}
|
||||
SpanImpl(std::vector<T> &v) : SpanImpl(v.data(), v.size()) {
|
||||
SpanImpl(vector<T> &v) : SpanImpl(v.data(), v.size()) {
|
||||
}
|
||||
|
||||
template <class OtherInnerT>
|
||||
@ -69,15 +71,17 @@ class SpanImpl {
|
||||
return *this;
|
||||
}
|
||||
|
||||
SpanImpl substr(size_t offset) {
|
||||
SpanImpl substr(size_t offset) const {
|
||||
CHECK(offset <= size_);
|
||||
return SpanImpl(begin() + offset, size_ - offset);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <class T>
|
||||
using Span = detail::SpanImpl<T, const T>;
|
||||
|
||||
template <class T>
|
||||
using MutableSpan = detail::SpanImpl<T, T>;
|
||||
}; // namespace td
|
||||
|
||||
} // namespace td
|
||||
|
@ -5,15 +5,19 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/Span.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace td {
|
||||
|
||||
template <class T>
|
||||
class VectorQueue {
|
||||
public:
|
||||
template <class S>
|
||||
void push(S&& s) {
|
||||
void push(S &&s) {
|
||||
vector_.push_back(std::forward<S>(s));
|
||||
}
|
||||
T pop() {
|
||||
@ -24,11 +28,11 @@ class VectorQueue {
|
||||
read_pos_ += n;
|
||||
try_shrink();
|
||||
}
|
||||
T& front() {
|
||||
T &front() {
|
||||
return vector_[read_pos_];
|
||||
}
|
||||
T& back() {
|
||||
vector_.back();
|
||||
T &back() {
|
||||
return vector_.back();
|
||||
}
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
@ -36,10 +40,10 @@ class VectorQueue {
|
||||
size_t size() const {
|
||||
return vector_.size() - read_pos_;
|
||||
}
|
||||
T* data() {
|
||||
T *data() {
|
||||
return vector_.data() + read_pos_;
|
||||
}
|
||||
const T* data() const {
|
||||
const T *data() const {
|
||||
return vector_.data() + read_pos_;
|
||||
}
|
||||
Span<T> as_span() const {
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
@ -638,7 +638,7 @@ class ChainBufferWriter {
|
||||
}
|
||||
|
||||
// legacy
|
||||
static ChainBufferWriter create_empty(size_t /*size*/ = 0) {
|
||||
static ChainBufferWriter create_empty() {
|
||||
return ChainBufferWriter();
|
||||
}
|
||||
|
||||
@ -764,6 +764,6 @@ class BufferBuilder {
|
||||
void append_slow(BufferSlice slice);
|
||||
bool prepend_inplace(Slice slice);
|
||||
void prepend_slow(BufferSlice slice);
|
||||
}; // namespace td
|
||||
};
|
||||
|
||||
} // namespace td
|
||||
|
@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/port/platform.h"
|
||||
//#include "td/utils/format.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@ -51,26 +50,26 @@ struct UInt {
|
||||
};
|
||||
|
||||
template <size_t size>
|
||||
inline bool operator==(const UInt<size> &a, const UInt<size> &b) {
|
||||
bool operator==(const UInt<size> &a, const UInt<size> &b) {
|
||||
return std::memcmp(a.raw, b.raw, sizeof(a.raw)) == 0;
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
inline td::UInt<size> operator^(const UInt<size> &a, const UInt<size> &b) {
|
||||
bool operator!=(const UInt<size> &a, const UInt<size> &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
td::UInt<size> operator^(const UInt<size> &a, const UInt<size> &b) {
|
||||
td::UInt<size> res;
|
||||
for (size_t i = 0; i * 8 < size; i++) {
|
||||
res.raw[i] = a.raw[i] ^ b.raw[i];
|
||||
res.raw[i] = static_cast<uint8>(a.raw[i] ^ b.raw[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
inline bool operator!=(const UInt<size> &a, const UInt<size> &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
inline bool is_zero(const UInt<size> &a) {
|
||||
bool is_zero(const UInt<size> &a) {
|
||||
for (size_t i = 0; i * 8 < size; i++) {
|
||||
if (a.raw[i]) {
|
||||
return false;
|
||||
@ -80,15 +79,15 @@ inline bool is_zero(const UInt<size> &a) {
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
inline int get_kth_bit(const UInt<size> &a, uint32 bit) {
|
||||
int get_kth_bit(const UInt<size> &a, uint32 bit) {
|
||||
uint8 b = a.raw[bit / 8];
|
||||
bit &= 7;
|
||||
return (b >> (7 - bit)) & 1;
|
||||
}
|
||||
|
||||
template <size_t size>
|
||||
inline bool operator<(const UInt<size> &a, const UInt<size> &b) {
|
||||
return memcmp(a.raw, b.raw, sizeof(a.raw)) < 0;
|
||||
bool operator<(const UInt<size> &a, const UInt<size> &b) {
|
||||
return std::memcmp(a.raw, b.raw, sizeof(a.raw)) < 0;
|
||||
}
|
||||
|
||||
using UInt128 = UInt<128>;
|
||||
|
@ -175,11 +175,6 @@ void tuple_for_each(const std::tuple<Args...> &tuple, const F &func) {
|
||||
detail::tuple_for_each_impl(tuple, func, detail::IntRange<sizeof...(Args)>());
|
||||
}
|
||||
|
||||
template <size_t N, class Arg, std::enable_if_t<N == 0> = 0>
|
||||
auto &&get_nth_argument(Arg &&arg) {
|
||||
return std::forward<Arg>(arg);
|
||||
}
|
||||
|
||||
template <size_t N, class Arg, class... Args, std::enable_if_t<N == 0, int> = 0>
|
||||
auto &&get_nth_argument(Arg &&arg, Args &&... args) {
|
||||
return std::forward<Arg>(arg);
|
||||
|
@ -55,7 +55,7 @@ Logger::Logger(LogInterface &log, const LogOptions &options, int log_level, Slic
|
||||
if (log_level < 10) {
|
||||
sb_ << ' ';
|
||||
}
|
||||
sb_ << log_level << "]";
|
||||
sb_ << log_level << ']';
|
||||
|
||||
// thread id
|
||||
auto thread_id = get_thread_id();
|
||||
@ -63,10 +63,10 @@ Logger::Logger(LogInterface &log, const LogOptions &options, int log_level, Slic
|
||||
if (thread_id < 10) {
|
||||
sb_ << ' ';
|
||||
}
|
||||
sb_ << thread_id << "]";
|
||||
sb_ << thread_id << ']';
|
||||
|
||||
// timestamp
|
||||
sb_ << "[" << StringBuilder::FixedDouble(Clocks::system(), 9) << "]";
|
||||
sb_ << '[' << StringBuilder::FixedDouble(Clocks::system(), 9) << ']';
|
||||
|
||||
// file : line
|
||||
if (!file_name.empty()) {
|
||||
@ -104,7 +104,7 @@ Logger::~Logger() {
|
||||
slice.back() = '\n';
|
||||
}
|
||||
while (slice.size() > 1 && slice[slice.size() - 2] == '\n') {
|
||||
slice.back() = 0;
|
||||
slice.back() = '\0';
|
||||
slice = MutableCSlice(slice.begin(), slice.begin() + slice.size() - 1);
|
||||
}
|
||||
log_.append(slice, log_level_);
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
#define PSTR_IMPL() ::td::Logger(::td::NullLog().ref(), ::td::LogOptions::plain(), 0)
|
||||
@ -81,10 +79,8 @@ inline bool no_return_func() {
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#ifdef CHECK
|
||||
#undef CHECK
|
||||
#endif
|
||||
#define DUMMY_CHECK(condition) LOG_IF(NEVER, !(condition))
|
||||
|
||||
#ifdef TD_DEBUG
|
||||
#if TD_MSVC
|
||||
#define CHECK(condition) \
|
||||
@ -96,10 +92,11 @@ inline bool no_return_func() {
|
||||
#else
|
||||
#define CHECK DUMMY_CHECK
|
||||
#endif
|
||||
|
||||
#if NDEBUG
|
||||
#define DCHECK DUMMY_CHECK
|
||||
#define DCHECK DUMMY_CHECK
|
||||
#else
|
||||
#define DCHECK CHECK
|
||||
#define DCHECK CHECK
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
@ -134,7 +131,12 @@ struct LogOptions {
|
||||
bool add_info{true};
|
||||
|
||||
static constexpr LogOptions plain() {
|
||||
return {0, false, false};
|
||||
return LogOptions{0, false, false};
|
||||
}
|
||||
|
||||
constexpr LogOptions() = default;
|
||||
constexpr LogOptions(int level, bool fix_newlines, bool add_info)
|
||||
: level(level), fix_newlines(fix_newlines), add_info(add_info) {
|
||||
}
|
||||
};
|
||||
|
||||
@ -151,7 +153,7 @@ class LogInterface {
|
||||
virtual void append(CSlice slice) {
|
||||
append(slice, -1);
|
||||
}
|
||||
virtual void append(CSlice slice, int /*log_level_*/) {
|
||||
virtual void append(CSlice slice, int /*log_level*/) {
|
||||
append(slice);
|
||||
}
|
||||
virtual void rotate() {
|
||||
@ -160,7 +162,7 @@ class LogInterface {
|
||||
|
||||
class NullLog : public LogInterface {
|
||||
public:
|
||||
void append(CSlice /*slice*/, int /*log_level_*/) override {
|
||||
void append(CSlice /*slice*/, int /*log_level*/) override {
|
||||
}
|
||||
void rotate() override {
|
||||
}
|
||||
|
@ -284,8 +284,8 @@ string url_encode(Slice str);
|
||||
|
||||
namespace detail {
|
||||
template <class T, class U>
|
||||
struct is_same_signedness : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value> {
|
||||
};
|
||||
struct is_same_signedness
|
||||
: public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value> {};
|
||||
|
||||
template <class T, class Enable = void>
|
||||
struct safe_undeflying_type {
|
||||
@ -350,6 +350,7 @@ bool is_aligned_pointer(const T *pointer) {
|
||||
return (reinterpret_cast<std::uintptr_t>(static_cast<const void *>(pointer)) & (Alignment - 1)) == 0;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct reversion_wrapper {
|
||||
T &iterable;
|
||||
@ -364,9 +365,10 @@ template <typename T>
|
||||
auto end(reversion_wrapper<T> w) {
|
||||
return rend(w.iterable);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
reversion_wrapper<T> reversed(T &&iterable) {
|
||||
detail::reversion_wrapper<T> reversed(T &iterable) {
|
||||
return {iterable};
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,9 @@ struct overload<F> : public F {
|
||||
};
|
||||
|
||||
template <class F, class... Fs>
|
||||
struct overload<F, Fs...> : public overload<F>, overload<Fs...> {
|
||||
struct overload<F, Fs...>
|
||||
: public overload<F>
|
||||
, overload<Fs...> {
|
||||
overload(F f, Fs... fs) : overload<F>(f), overload<Fs...>(fs...) {
|
||||
}
|
||||
using overload<F>::operator();
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
|
@ -15,11 +15,10 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
@ -134,7 +133,6 @@ Result<FileFd> FileFd::open(CSlice filepath, int32 flags, int32 mode) {
|
||||
if (native_fd < 0) {
|
||||
return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags});
|
||||
}
|
||||
|
||||
return from_native_fd(NativeFd(native_fd));
|
||||
#elif TD_PORT_WINDOWS
|
||||
// TODO: support modes
|
||||
@ -187,15 +185,14 @@ Result<FileFd> FileFd::open(CSlice filepath, int32 flags, int32 mode) {
|
||||
offset.QuadPart = 0;
|
||||
auto set_pointer_res = SetFilePointerEx(handle, offset, nullptr, FILE_END);
|
||||
if (!set_pointer_res) {
|
||||
auto res = OS_ERROR(PSLICE() << "Failed to seek to the end of file \"" << filepath << "\"");
|
||||
return res;
|
||||
return OS_ERROR(PSLICE() << "Failed to seek to the end of file \"" << filepath << "\"");
|
||||
}
|
||||
}
|
||||
return from_native_fd(std::move(native_fd));
|
||||
#endif
|
||||
}
|
||||
|
||||
Result<FileFd> FileFd::from_native_fd(NativeFd native_fd) {
|
||||
FileFd FileFd::from_native_fd(NativeFd native_fd) {
|
||||
auto impl = std::make_unique<detail::FileFdImpl>();
|
||||
impl->info.set_native_fd(std::move(native_fd));
|
||||
impl->info.add_flags(PollFlags::Write());
|
||||
@ -508,9 +505,11 @@ Status FileFd::truncate_to_current_position(int64 current_position) {
|
||||
return Status::OK();
|
||||
}
|
||||
PollableFdInfo &FileFd::get_poll_info() {
|
||||
CHECK(!empty());
|
||||
return impl_->info;
|
||||
}
|
||||
const PollableFdInfo &FileFd::get_poll_info() const {
|
||||
CHECK(!empty());
|
||||
return impl_->info;
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
#include "td/utils/port/config.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
@ -32,7 +32,7 @@ class FileFd {
|
||||
enum Flags : int32 { Write = 1, Read = 2, Truncate = 4, Create = 8, Append = 16, CreateNew = 32 };
|
||||
|
||||
static Result<FileFd> open(CSlice filepath, int32 flags, int32 mode = 0600) TD_WARN_UNUSED_RESULT;
|
||||
static Result<FileFd> from_native_fd(NativeFd fd) TD_WARN_UNUSED_RESULT;
|
||||
static FileFd from_native_fd(NativeFd fd) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<size_t> write(Slice slice) TD_WARN_UNUSED_RESULT;
|
||||
Result<size_t> read(MutableSlice slice) TD_WARN_UNUSED_RESULT;
|
||||
@ -64,7 +64,7 @@ class FileFd {
|
||||
private:
|
||||
std::unique_ptr<detail::FileFdImpl> impl_;
|
||||
|
||||
FileFd(std::unique_ptr<detail::FileFdImpl> impl);
|
||||
explicit FileFd(std::unique_ptr<detail::FileFdImpl> impl);
|
||||
};
|
||||
|
||||
} // namespace td
|
||||
|
@ -369,16 +369,15 @@ Status IPAddress::init_sockaddr(sockaddr *addr, socklen_t len) {
|
||||
if (addr->sa_family == AF_INET6) {
|
||||
CHECK(len == sizeof(ipv6_addr_));
|
||||
std::memcpy(&ipv6_addr_, reinterpret_cast<sockaddr_in6 *>(addr), sizeof(ipv6_addr_));
|
||||
LOG(DEBUG) << "Have ipv6 address " << get_ip_str() << " with port " << get_port();
|
||||
} else if (addr->sa_family == AF_INET) {
|
||||
CHECK(len == sizeof(ipv4_addr_));
|
||||
std::memcpy(&ipv4_addr_, reinterpret_cast<sockaddr_in *>(addr), sizeof(ipv4_addr_));
|
||||
LOG(DEBUG) << "Have ipv4 address " << get_ip_str() << " with port " << get_port();
|
||||
} else {
|
||||
return Status::Error(PSLICE() << "Unknown " << tag("sa_family", addr->sa_family));
|
||||
}
|
||||
|
||||
is_valid_ = true;
|
||||
LOG(INFO) << "Have address " << get_ip_str() << " with port " << get_port();
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ class IPAddress {
|
||||
sockaddr_in ipv4_addr_;
|
||||
sockaddr_in6 ipv6_addr_;
|
||||
};
|
||||
socklen_t storage_size() {
|
||||
static constexpr socklen_t storage_size() {
|
||||
return sizeof(ipv6_addr_);
|
||||
}
|
||||
bool is_valid_;
|
||||
|
@ -6,7 +6,6 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -29,13 +29,15 @@
|
||||
#include "td/utils/VectorQueue.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace td {
|
||||
|
||||
namespace detail {
|
||||
#if TD_PORT_WINDOWS
|
||||
class ServerSocketFdImpl : private IOCP::Callback {
|
||||
public:
|
||||
ServerSocketFdImpl(NativeFd fd, int socket_family) : info(std::move(fd)), socket_family_(socket_family) {
|
||||
ServerSocketFdImpl(NativeFd fd, int socket_family) : info_(std::move(fd)), socket_family_(socket_family) {
|
||||
VLOG(fd) << get_native_fd().io_handle() << " create ServerSocketFd";
|
||||
IOCP::get()->subscribe(get_native_fd(), this);
|
||||
notify_iocp_read();
|
||||
@ -44,14 +46,14 @@ class ServerSocketFdImpl : private IOCP::Callback {
|
||||
notify_iocp_close();
|
||||
}
|
||||
PollableFdInfo &get_poll_info() {
|
||||
return info;
|
||||
return info_;
|
||||
}
|
||||
const PollableFdInfo &get_poll_info() const {
|
||||
return info;
|
||||
return info_;
|
||||
}
|
||||
|
||||
const NativeFd &get_native_fd() const {
|
||||
return info.native_fd();
|
||||
return info_.native_fd();
|
||||
}
|
||||
|
||||
Result<SocketFd> accept() {
|
||||
@ -78,7 +80,7 @@ class ServerSocketFdImpl : private IOCP::Callback {
|
||||
}
|
||||
|
||||
private:
|
||||
PollableFdInfo info;
|
||||
PollableFdInfo info_;
|
||||
|
||||
SpinLock lock_;
|
||||
VectorQueue<SocketFd> accepted_;
|
||||
@ -98,7 +100,7 @@ class ServerSocketFdImpl : private IOCP::Callback {
|
||||
|
||||
void on_close() {
|
||||
close_flag_ = true;
|
||||
info.set_native_fd({});
|
||||
info_.set_native_fd({});
|
||||
}
|
||||
void on_read() {
|
||||
VLOG(fd) << get_native_fd().io_handle() << " on_read";
|
||||
@ -133,7 +135,7 @@ class ServerSocketFdImpl : private IOCP::Callback {
|
||||
if (status == 0) {
|
||||
return true;
|
||||
}
|
||||
auto last_error = GetLastError();
|
||||
auto last_error = WSAGetLastError();
|
||||
if (last_error == ERROR_IO_PENDING) {
|
||||
return true;
|
||||
}
|
||||
@ -197,17 +199,17 @@ void ServerSocketFdImplDeleter::operator()(ServerSocketFdImpl *impl) {
|
||||
#elif TD_PORT_POSIX
|
||||
class ServerSocketFdImpl {
|
||||
public:
|
||||
ServerSocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
explicit ServerSocketFdImpl(NativeFd fd) : info_(std::move(fd)) {
|
||||
}
|
||||
PollableFdInfo &get_poll_info() {
|
||||
return info;
|
||||
return info_;
|
||||
}
|
||||
const PollableFdInfo &get_poll_info() const {
|
||||
return info;
|
||||
return info_;
|
||||
}
|
||||
|
||||
const NativeFd &get_native_fd() const {
|
||||
return info.native_fd();
|
||||
return info_.native_fd();
|
||||
}
|
||||
Result<SocketFd> accept() {
|
||||
sockaddr_storage addr;
|
||||
@ -260,7 +262,7 @@ class ServerSocketFdImpl {
|
||||
}
|
||||
|
||||
private:
|
||||
PollableFdInfo info;
|
||||
PollableFdInfo info_;
|
||||
};
|
||||
void ServerSocketFdImplDeleter::operator()(ServerSocketFdImpl *impl) {
|
||||
delete impl;
|
||||
|
@ -6,7 +6,8 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
|
||||
#include "td/utils/Slice.h"
|
||||
|
@ -7,9 +7,15 @@
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/port/detail/WineventPoll.h"
|
||||
#include "td/utils/SpinLock.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
#endif
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
@ -20,19 +26,14 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/port/detail/WineventPoll.h"
|
||||
#include "td/utils/SpinLock.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
#endif
|
||||
#include <cstring>
|
||||
|
||||
namespace td {
|
||||
namespace detail {
|
||||
#if TD_PORT_WINDOWS
|
||||
class SocketFdImpl : private IOCP::Callback {
|
||||
public:
|
||||
SocketFdImpl(NativeFd native_fd) : info(std::move(native_fd)) {
|
||||
explicit SocketFdImpl(NativeFd native_fd) : info(std::move(native_fd)) {
|
||||
VLOG(fd) << get_native_fd().io_handle() << " create from native_fd";
|
||||
get_poll_info().add_flags(PollFlags::Write());
|
||||
IOCP::get()->subscribe(get_native_fd(), this);
|
||||
@ -95,7 +96,6 @@ class SocketFdImpl : private IOCP::Callback {
|
||||
if (res == 0) {
|
||||
get_poll_info().clear_flags(PollFlags::Read());
|
||||
}
|
||||
LOG(ERROR) << "GOT " << res;
|
||||
return res;
|
||||
}
|
||||
Status get_pending_error() {
|
||||
@ -138,7 +138,7 @@ class SocketFdImpl : private IOCP::Callback {
|
||||
if (status == 0) {
|
||||
return true;
|
||||
}
|
||||
auto last_error = GetLastError();
|
||||
auto last_error = WSAGetLastError();
|
||||
if (last_error == ERROR_IO_PENDING) {
|
||||
return true;
|
||||
}
|
||||
@ -271,7 +271,6 @@ class SocketFdImpl : private IOCP::Callback {
|
||||
}
|
||||
bool dec_refcnt() {
|
||||
if (--refcnt_ == 0) {
|
||||
LOG(ERROR) << "DELETE";
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
@ -318,7 +317,7 @@ static InitWSA init_wsa;
|
||||
class SocketFdImpl {
|
||||
public:
|
||||
PollableFdInfo info;
|
||||
SocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
explicit SocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
}
|
||||
PollableFdInfo &get_poll_info() {
|
||||
return info;
|
||||
|
@ -8,9 +8,10 @@
|
||||
|
||||
#include "td/utils/port/config.h"
|
||||
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
@ -23,6 +24,7 @@ class SocketFdImplDeleter {
|
||||
};
|
||||
class EventFdBsd;
|
||||
} // namespace detail
|
||||
|
||||
class SocketFd {
|
||||
public:
|
||||
SocketFd();
|
||||
|
@ -6,12 +6,14 @@
|
||||
//
|
||||
#include "td/utils/port/StdStreams.h"
|
||||
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
namespace {
|
||||
template <class T>
|
||||
FileFd create(T handle) {
|
||||
return FileFd::from_native_fd(NativeFd(handle, true)).move_as_ok();
|
||||
return FileFd::from_native_fd(NativeFd(handle, true));
|
||||
}
|
||||
} // namespace
|
||||
FileFd &Stdin() {
|
||||
|
@ -5,6 +5,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/port/FileFd.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -6,10 +6,16 @@
|
||||
//
|
||||
#include "td/utils/port/UdpSocketFd.h"
|
||||
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
#include "td/utils/port/detail/WineventPoll.h"
|
||||
#endif
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
#include <arpa/inet.h>
|
||||
@ -25,11 +31,8 @@
|
||||
#endif
|
||||
#endif // TD_PORT_POSIX
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
#include <Mswsock.h>
|
||||
#include "td/utils/port/Poll.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
#endif
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
namespace td {
|
||||
namespace detail {
|
||||
@ -64,7 +67,7 @@ class UdpSocketReceiveHelper {
|
||||
message.data.truncate(message_size);
|
||||
CHECK(message_size == message.data.size());
|
||||
if (message_size >= 1500) {
|
||||
LOG(ERROR) << "received datagram of size " << message_size;
|
||||
LOG(ERROR) << "Received datagram of size " << message_size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +97,7 @@ class UdpSocketSendHelper {
|
||||
|
||||
class UdpSocketFdImpl : private IOCP::Callback {
|
||||
public:
|
||||
UdpSocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
explicit UdpSocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
get_poll_info().add_flags(PollFlags::Write());
|
||||
IOCP::get()->subscribe(get_native_fd(), this);
|
||||
is_receive_active_ = true;
|
||||
@ -176,7 +179,7 @@ class UdpSocketFdImpl : private IOCP::Callback {
|
||||
if (status == 0) {
|
||||
return true;
|
||||
}
|
||||
auto last_error = GetLastError();
|
||||
auto last_error = WSAGetLastError();
|
||||
if (last_error == ERROR_IO_PENDING) {
|
||||
return true;
|
||||
}
|
||||
@ -296,7 +299,7 @@ class UdpSocketFdImpl : private IOCP::Callback {
|
||||
receive_buffer_.confirm_read((to_receive_.data.size() + 7) & ~7);
|
||||
{
|
||||
auto lock = lock_.lock();
|
||||
LOG(ERROR) << format::escaped(to_receive_.data.as_slice());
|
||||
// LOG(ERROR) << format::escaped(to_receive_.data.as_slice());
|
||||
receive_queue_.push(std::move(to_receive_));
|
||||
}
|
||||
get_poll_info().add_flags_from_poll(PollFlags::Read());
|
||||
@ -324,7 +327,6 @@ class UdpSocketFdImpl : private IOCP::Callback {
|
||||
|
||||
bool dec_refcnt() {
|
||||
if (--refcnt_ == 0) {
|
||||
LOG(ERROR) << "DELETE";
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
@ -465,7 +467,7 @@ class UdpSocketSendHelper {
|
||||
|
||||
class UdpSocketFdImpl {
|
||||
public:
|
||||
UdpSocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
explicit UdpSocketFdImpl(NativeFd fd) : info(std::move(fd)) {
|
||||
}
|
||||
PollableFdInfo &get_poll_info() {
|
||||
return info;
|
||||
@ -581,11 +583,11 @@ class UdpSocketFdImpl {
|
||||
case EMSGSIZE:
|
||||
case EPERM:
|
||||
LOG(WARNING) << "Silently drop packet :( " << error;
|
||||
//TODO: get errors from MSG_ERRQUEUE is possible
|
||||
//TODO: get errors from MSG_ERRQUEUE is possible
|
||||
is_sent = true;
|
||||
return error;
|
||||
|
||||
// Some general problems, wich may be fixed in future
|
||||
// Some general problems, which may be fixed in future
|
||||
case ENOMEM:
|
||||
case EDQUOT:
|
||||
case EFBIG:
|
||||
@ -658,7 +660,7 @@ class UdpSocketFdImpl {
|
||||
//};
|
||||
struct std::array<detail::UdpSocketSendHelper, 16> helpers;
|
||||
struct std::array<struct mmsghdr, 16> headers;
|
||||
size_t to_send = std::min(messages.size(), headers.size());
|
||||
size_t to_send = td::min(messages.size(), headers.size());
|
||||
for (size_t i = 0; i < to_send; i++) {
|
||||
helpers[i].to_native(messages[i], headers[i].msg_hdr);
|
||||
headers[i].msg_len = 0;
|
||||
@ -709,7 +711,7 @@ class UdpSocketFdImpl {
|
||||
//};
|
||||
struct std::array<detail::UdpSocketReceiveHelper, 16> helpers;
|
||||
struct std::array<struct mmsghdr, 16> headers;
|
||||
size_t to_receive = std::min(messages.size(), headers.size());
|
||||
size_t to_receive = td::min(messages.size(), headers.size());
|
||||
for (size_t i = 0; i < to_receive; i++) {
|
||||
helpers[i].to_native(messages[i], headers[i].msg_hdr);
|
||||
headers[i].msg_len = 0;
|
||||
@ -751,24 +753,6 @@ const PollableFdInfo &UdpSocketFd::get_poll_info() const {
|
||||
return impl_->get_poll_info();
|
||||
}
|
||||
|
||||
//Result<UdpSocketFd> UdpSocketFd::from_native_fd(int fd) {
|
||||
//auto fd_guard = ScopeExit() + [fd]() { ::close(fd); };
|
||||
|
||||
//TRY_STATUS(detail::set_native_socket_is_blocking(fd, false));
|
||||
|
||||
//// TODO remove copypaste
|
||||
//int flags = 1;
|
||||
//setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&flags), sizeof(flags));
|
||||
//setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<const char *>(&flags), sizeof(flags));
|
||||
//// TODO: SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_SNDBUF, SO_RCVBUF, TCP_QUICKACK, SO_LINGER
|
||||
|
||||
//fd_guard.dismiss();
|
||||
|
||||
//UdpSocketFd socket;
|
||||
//socket.fd_ = Fd(fd, Fd::Mode::Owner);
|
||||
//return std::move(socket);
|
||||
//}
|
||||
|
||||
Result<UdpSocketFd> UdpSocketFd::open(const IPAddress &address) {
|
||||
NativeFd native_fd{socket(address.get_address_family(), SOCK_DGRAM, IPPROTO_UDP)};
|
||||
if (!native_fd) {
|
||||
|
@ -8,13 +8,14 @@
|
||||
|
||||
#include "td/utils/port/config.h"
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/optional.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/Span.h"
|
||||
#include "td/utils/optional.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
// Udp and errors
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifdef TD_POLL_EPOLL
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
@ -11,8 +11,9 @@ char disable_linker_warning_about_empty_file_event_fd_bsd_cpp TD_UNUSED;
|
||||
#ifdef TD_EVENTFD_BSD
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifdef TD_EVENTFD_BSD
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/EventFdBase.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
@ -6,14 +6,13 @@
|
||||
//
|
||||
#include "td/utils/port/detail/EventFdLinux.h"
|
||||
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
char disable_linker_warning_about_empty_file_event_fd_linux_cpp TD_UNUSED;
|
||||
|
||||
#ifdef TD_EVENTFD_LINUX
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <sys/eventfd.h>
|
||||
|
@ -11,8 +11,8 @@
|
||||
#ifdef TD_EVENTFD_LINUX
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/EventFdBase.h"
|
||||
#include "td/utils/port/SocketFd.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -11,8 +11,9 @@
|
||||
#ifdef TD_EVENTFD_WINDOWS
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/EventFdBase.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/EventFdBase.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifdef TD_POLL_KQUEUE
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
@ -5,45 +5,54 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace td {
|
||||
NativeFd::NativeFd(NativeFd::Raw raw) : fd_(raw) {
|
||||
|
||||
NativeFd::NativeFd(Raw raw) : fd_(raw) {
|
||||
VLOG(fd) << *this << " create";
|
||||
}
|
||||
NativeFd::NativeFd(NativeFd::Raw raw, bool nolog) : fd_(raw) {
|
||||
|
||||
NativeFd::NativeFd(Raw raw, bool nolog) : fd_(raw) {
|
||||
}
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
NativeFd::NativeFd(SOCKET raw) : fd_(reinterpret_cast<HANDLE>(raw)), is_socket_(true) {
|
||||
VLOG(fd) << *this << " create";
|
||||
}
|
||||
#endif
|
||||
|
||||
NativeFd::~NativeFd() {
|
||||
close();
|
||||
}
|
||||
|
||||
NativeFd::operator bool() const {
|
||||
return fd_.get() != empty_raw();
|
||||
}
|
||||
constexpr NativeFd::Raw NativeFd::empty_raw() {
|
||||
|
||||
NativeFd::Raw NativeFd::empty_raw() {
|
||||
#if TD_PORT_POSIX
|
||||
return -1;
|
||||
#elif TD_PORT_WINDOWS
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
NativeFd::Raw NativeFd::raw() const {
|
||||
return fd_.get();
|
||||
}
|
||||
|
||||
NativeFd::Raw NativeFd::fd() const {
|
||||
return raw();
|
||||
}
|
||||
|
||||
#if TD_PORT_WINDOWS
|
||||
NativeFd::Raw NativeFd::io_handle() const {
|
||||
return raw();
|
||||
@ -57,13 +66,14 @@ NativeFd::Raw NativeFd::socket() const {
|
||||
return raw();
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeFd::close() {
|
||||
if (!*this) {
|
||||
return;
|
||||
}
|
||||
VLOG(fd) << *this << " close";
|
||||
#if TD_PORT_WINDOWS
|
||||
if (!CloseHandle(io_handle())) {
|
||||
if (is_socket_ ? closesocket(socket()) : !CloseHandle(io_handle())) {
|
||||
#elif TD_PORT_POSIX
|
||||
if (::close(fd()) < 0) {
|
||||
#endif
|
||||
@ -72,6 +82,7 @@ void NativeFd::close() {
|
||||
}
|
||||
fd_ = {};
|
||||
}
|
||||
|
||||
NativeFd::Raw NativeFd::release() {
|
||||
VLOG(fd) << *this << " release";
|
||||
auto res = fd_.get();
|
||||
@ -80,7 +91,7 @@ NativeFd::Raw NativeFd::release() {
|
||||
}
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &sb, const NativeFd &fd) {
|
||||
sb << tag("fd", fd.raw());
|
||||
return sb;
|
||||
return sb << tag("fd", fd.raw());
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -5,14 +5,14 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
#include "td/utils/port/config.h"
|
||||
#include "td/utils/common.h"
|
||||
|
||||
#include "td/utils/port/config.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/MovableValue.h"
|
||||
|
||||
namespace td {
|
||||
class StringBuilder;
|
||||
}
|
||||
namespace td {
|
||||
|
||||
class NativeFd {
|
||||
public:
|
||||
#if TD_PORT_POSIX
|
||||
@ -24,6 +24,7 @@ class NativeFd {
|
||||
NativeFd(NativeFd &&) = default;
|
||||
NativeFd &operator=(NativeFd &&) = default;
|
||||
explicit NativeFd(Raw raw);
|
||||
NativeFd &operator=(const NativeFd &) = delete;
|
||||
NativeFd(Raw raw, bool nolog);
|
||||
#if TD_PORT_WINDOWS
|
||||
explicit NativeFd(SOCKET raw);
|
||||
@ -31,7 +32,7 @@ class NativeFd {
|
||||
~NativeFd();
|
||||
|
||||
explicit operator bool() const;
|
||||
static constexpr Raw empty_raw();
|
||||
static Raw empty_raw();
|
||||
Raw raw() const;
|
||||
Raw fd() const;
|
||||
#if TD_PORT_WINDOWS
|
||||
@ -52,5 +53,7 @@ class NativeFd {
|
||||
#endif
|
||||
};
|
||||
|
||||
class StringBuilder;
|
||||
StringBuilder &operator<<(StringBuilder &sb, const NativeFd &fd);
|
||||
|
||||
} // namespace td
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifdef TD_POLL_POLL
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
|
||||
#include <poll.h>
|
||||
|
@ -5,16 +5,17 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/Observer.h"
|
||||
#include "td/utils/MovableValue.h"
|
||||
#include "td/utils/SpinLock.h"
|
||||
#include "td/utils/format.h"
|
||||
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/MovableValue.h"
|
||||
#include "td/utils/Observer.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/SpinLock.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace td {
|
||||
class ObserverBase;
|
||||
|
||||
@ -321,6 +322,7 @@ inline PollFlags PollableFd::get_flags_unsafe() const {
|
||||
inline const NativeFd &PollableFd::native_fd() const {
|
||||
return fd_info_->native_fd();
|
||||
}
|
||||
|
||||
#if TD_PORT_POSIX
|
||||
template <class F>
|
||||
auto skip_eintr(F &&f) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifdef TD_POLL_SELECT
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifdef TD_THREAD_PTHREAD
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Destructor.h"
|
||||
#include "td/utils/invoke.h"
|
||||
#include "td/utils/MovableValue.h"
|
||||
#include "td/utils/port/detail/ThreadIdGuard.h"
|
||||
|
@ -13,9 +13,7 @@ char disable_linker_warning_about_empty_file_wineventpoll_cpp TD_UNUSED;
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <utility>
|
||||
@ -32,14 +30,14 @@ void IOCP::loop() {
|
||||
DWORD bytes = 0;
|
||||
ULONG_PTR key = 0;
|
||||
OVERLAPPED *overlapped = nullptr;
|
||||
bool ok = GetQueuedCompletionStatus(iocp_handle_.io_handle(), &bytes, &key, &overlapped, 1000);
|
||||
BOOL ok = GetQueuedCompletionStatus(iocp_handle_.io_handle(), &bytes, &key, &overlapped, 1000);
|
||||
if (bytes || key || overlapped) {
|
||||
LOG(ERROR) << "Got iocp " << bytes << " " << key << " " << overlapped;
|
||||
// LOG(ERROR) << "Got iocp " << bytes << " " << key << " " << overlapped;
|
||||
}
|
||||
if (ok) {
|
||||
auto callback = reinterpret_cast<IOCP::Callback *>(key);
|
||||
if (callback == nullptr) {
|
||||
LOG(ERROR) << "Interrupt IOCP loop";
|
||||
// LOG(ERROR) << "Interrupt IOCP loop";
|
||||
return;
|
||||
}
|
||||
callback->on_iocp(bytes, overlapped);
|
||||
|
@ -12,7 +12,8 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Context.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/PollBase.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
|
||||
@ -70,8 +71,6 @@ class WineventPoll final : public PollBase {
|
||||
static bool is_edge_triggered() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
@ -6,8 +6,6 @@
|
||||
//
|
||||
#include "td/utils/port/path.h"
|
||||
|
||||
#include "td/utils/port/Fd.h"
|
||||
|
||||
#if TD_WINDOWS
|
||||
#include "td/utils/Random.h"
|
||||
#endif
|
||||
|
@ -50,7 +50,7 @@ void do_init_thread_local(P &raw_ptr, ArgsT &&... args) {
|
||||
ptr.reset();
|
||||
raw_ptr = nullptr;
|
||||
}));
|
||||
} // namespace detail
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <class T, class P, class... ArgsT>
|
||||
|
@ -14,7 +14,7 @@ struct member_function_class;
|
||||
template <class ReturnType, class Type, class... Args>
|
||||
struct member_function_class<ReturnType (Type::*)(Args...)> {
|
||||
using type = Type;
|
||||
constexpr static size_t arguments_count() {
|
||||
static constexpr size_t argument_count() {
|
||||
return sizeof...(Args);
|
||||
}
|
||||
};
|
||||
@ -23,8 +23,8 @@ template <class FunctionT>
|
||||
using member_function_class_t = typename member_function_class<FunctionT>::type;
|
||||
|
||||
template <class FunctionT>
|
||||
constexpr size_t member_function_arguments_count() {
|
||||
return member_function_class<FunctionT>::arguments_count();
|
||||
constexpr size_t member_function_argument_count() {
|
||||
return member_function_class<FunctionT>::argument_count();
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -28,7 +28,6 @@ TEST(Buffer, buffer_builder) {
|
||||
builder.append(" B");
|
||||
ASSERT_EQ(builder.extract().as_slice(), "A hello B");
|
||||
}
|
||||
//Slice slice(std::string());
|
||||
{
|
||||
std::string str = rand_string('a', 'z', 10000);
|
||||
auto splitted_str = rand_split(str);
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include "td/utils/base64.h"
|
||||
#include "td/utils/BigNum.h"
|
||||
#include "td/utils/HttpUrl.h"
|
||||
#include "td/utils/invoke.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/invoke.h"
|
||||
#include "td/utils/port/EventFd.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
|
@ -4,9 +4,11 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/utils/tests.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/tests.h"
|
||||
|
||||
using namespace td;
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "td/utils/GzipByteFlow.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Fd.h"
|
||||
#include "td/utils/port/detail/PollableFd.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
|
Loading…
Reference in New Issue
Block a user