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