A lot of fixes.

GitOrigin-RevId: c7c16991da51e09a685537a444385852e8e93af4
This commit is contained in:
levlam 2018-09-07 03:41:21 +03:00
parent cfcc08ebb7
commit fd90bf435e
77 changed files with 318 additions and 274 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -9,6 +9,7 @@
#include "td/utils/port/thread_local.h"
namespace td {
template <class Impl>
class Context {
public:

View File

@ -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;
}
};

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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;
}

View File

@ -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()();

View File

@ -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) {
}

View File

@ -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();
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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>;

View File

@ -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);

View File

@ -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_);

View File

@ -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 {
}

View File

@ -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};
}

View File

@ -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();

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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_;

View File

@ -6,7 +6,6 @@
//
#pragma once
#include "td/utils/port/Fd.h"
#include "td/utils/port/detail/PollableFd.h"
namespace td {

View File

@ -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;

View File

@ -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"

View File

@ -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;

View File

@ -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();

View File

@ -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() {

View File

@ -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 {

View File

@ -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) {

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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 {

View File

@ -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 {

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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) {

View File

@ -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>

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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"