diff --git a/td/telegram/files/FileDownloader.cpp b/td/telegram/files/FileDownloader.cpp index 900c0cbb..dd9d8449 100644 --- a/td/telegram/files/FileDownloader.cpp +++ b/td/telegram/files/FileDownloader.cpp @@ -331,16 +331,15 @@ Result FileDownloader::process_part(Part part, NetQueryPtr net_query) { // Encryption if (need_cdn_decrypt) { - UInt128 iv = as(cdn_encryption_iv_.c_str()); CHECK(part.offset % 16 == 0); auto offset = narrow_cast(part.offset / 16); offset = ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) | ((offset & 0xff0000) >> 8) | ((offset & 0xff000000) >> 24); - as(iv.raw + 12) = offset; - UInt256 key = as(cdn_encryption_key_.c_str()); AesCtrState ctr_state; - ctr_state.init(as_slice(key), as_slice(iv)); + string iv = cdn_encryption_iv_; + as(&iv[12]) = offset; + ctr_state.init(cdn_encryption_key_, iv); ctr_state.decrypt(bytes.as_slice(), bytes.as_slice()); } if (encryption_key_.is_secret()) { diff --git a/tdactor/test/actors_main.cpp b/tdactor/test/actors_main.cpp index ef08e279..269c8555 100644 --- a/tdactor/test/actors_main.cpp +++ b/tdactor/test/actors_main.cpp @@ -481,7 +481,7 @@ class XContext : public ActorContext { int x = 1234; }; -class WithContext : public Actor { +class WithXContext : public Actor { public: void start_up() override { set_context(std::make_shared()); @@ -491,8 +491,6 @@ class WithContext : public Actor { void close() { stop(); } - - private: }; void check_context() { @@ -510,11 +508,11 @@ TEST(Actors, context_during_destruction) { { auto guard = sched.get_main_guard(); - auto with_context = create_actor("WithContext").release(); - send_closure(with_context, &WithContext::f, create_lambda_guard([] { check_context(); })); - send_closure_later(with_context, &WithContext::close); - send_closure(with_context, &WithContext::f, create_lambda_guard([] { check_context(); })); - send_closure(with_context, &WithContext::f, create_lambda_guard([] { Scheduler::instance()->finish(); })); + auto with_context = create_actor("WithXContext").release(); + send_closure(with_context, &WithXContext::f, create_lambda_guard([] { check_context(); })); + send_closure_later(with_context, &WithXContext::close); + send_closure(with_context, &WithXContext::f, create_lambda_guard([] { check_context(); })); + send_closure(with_context, &WithXContext::f, create_lambda_guard([] { Scheduler::instance()->finish(); })); } sched.start(); while (sched.run_main(10)) { diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index bb77063c..307ca238 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -99,17 +99,17 @@ set(TDUTILS_SOURCE td/utils/MpmcQueue.cpp td/utils/OptionsParser.cpp td/utils/Random.cpp - td/utils/Slice.cpp td/utils/SharedSlice.cpp + td/utils/Slice.cpp td/utils/StackAllocator.cpp td/utils/Status.cpp td/utils/StringBuilder.cpp + td/utils/tests.cpp td/utils/Time.cpp td/utils/Timer.cpp - td/utils/TsFileLog.cpp - td/utils/tests.cpp td/utils/tl_parsers.cpp td/utils/translit.cpp + td/utils/TsFileLog.cpp td/utils/unicode.cpp td/utils/utf8.cpp @@ -220,6 +220,7 @@ set(TDUTILS_SOURCE td/utils/Random.h td/utils/ScopeGuard.h td/utils/SharedObjectPool.h + td/utils/SharedSlice.h td/utils/Slice-decl.h td/utils/Slice.h td/utils/Span.h @@ -230,15 +231,16 @@ set(TDUTILS_SOURCE td/utils/StorerBase.h td/utils/StringBuilder.h td/utils/tests.h + td/utils/ThreadLocalStorage.h td/utils/ThreadSafeCounter.h td/utils/Time.h td/utils/TimedStat.h td/utils/Timer.h - td/utils/TsFileLog.h td/utils/tl_helpers.h td/utils/tl_parsers.h td/utils/tl_storers.h td/utils/translit.h + td/utils/TsFileLog.h td/utils/type_traits.h td/utils/UInt.h td/utils/uint128.h @@ -254,6 +256,7 @@ set(TDUTILS_TEST_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/test/ConcurrentHashMap.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/crypto.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/Enumerator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/EpochBasedMemoryReclamation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/filesystem.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/gzip.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/HazardPointers.cpp diff --git a/tdutils/td/utils/FileLog.h b/tdutils/td/utils/FileLog.h index 145d6ac8..c801b1cf 100644 --- a/tdutils/td/utils/FileLog.h +++ b/tdutils/td/utils/FileLog.h @@ -37,7 +37,7 @@ class FileLog : public LogInterface { string path_; int64 size_ = 0; int64 rotate_threshold_ = 0; - bool redirect_stderr_; + bool redirect_stderr_ = false; void do_rotate(); }; diff --git a/tdutils/td/utils/SharedSlice.cpp b/tdutils/td/utils/SharedSlice.cpp index 17b937cf..3dd76699 100644 --- a/tdutils/td/utils/SharedSlice.cpp +++ b/tdutils/td/utils/SharedSlice.cpp @@ -11,7 +11,7 @@ namespace td { BufferSlice SharedSlice::clone_as_buffer_slice() const { - return BufferSlice{as_slice().str()}; + return BufferSlice{as_slice()}; } } // namespace td diff --git a/tdutils/td/utils/SharedSlice.h b/tdutils/td/utils/SharedSlice.h index 39735aa6..67e806e8 100644 --- a/tdutils/td/utils/SharedSlice.h +++ b/tdutils/td/utils/SharedSlice.h @@ -15,7 +15,7 @@ namespace td { namespace detail { struct SharedSliceHeader { - explicit SharedSliceHeader(size_t size) : refcnt_{1}, size_{size} { + explicit SharedSliceHeader(size_t size) : size_{size} { } void inc() { @@ -37,7 +37,7 @@ struct SharedSliceHeader { } private: - std::atomic refcnt_; + std::atomic refcnt_{1}; size_t size_; }; @@ -107,9 +107,9 @@ class UnsafeSharedSlice { static UnsafeSharedSlice create(size_t size) { static_assert(std::is_standard_layout::value, "HeaderT must have statdard layout"); - auto ptr = std::make_unique(size + sizeof(HeaderT)); + auto ptr = std::make_unique(sizeof(HeaderT) + size); auto header_ptr = new (ptr.get()) HeaderT(size); - CHECK(reinterpret_cast(header_ptr) == ptr.get()); + CHECK(header_ptr == reinterpret_cast(ptr.get())); return UnsafeSharedSlice(std::move(ptr)); } @@ -160,8 +160,7 @@ class SharedSlice { public: SharedSlice() = default; - explicit SharedSlice(Slice slice) : impl_(Impl::create(slice.size())) { - impl_.as_mutable_slice().copy_from(slice); + explicit SharedSlice(Slice slice) : impl_(Impl::create(slice)) { } explicit SharedSlice(UniqueSharedSlice from); @@ -301,7 +300,7 @@ class UniqueSliceImpl { explicit UniqueSliceImpl(size_t size) : impl_(Impl::create(size)) { } UniqueSliceImpl(size_t size, char c) : impl_(Impl::create(size)) { - std::memset(as_mutable_slice().data(), c, size); + as_mutable_slice().fill(c); } explicit UniqueSliceImpl(Slice slice) : impl_(Impl::create(slice)) { } diff --git a/tdutils/td/utils/Slice.cpp b/tdutils/td/utils/Slice.cpp index e965ab85..ed2d1630 100644 --- a/tdutils/td/utils/Slice.cpp +++ b/tdutils/td/utils/Slice.cpp @@ -5,6 +5,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/utils/Slice.h" + #if TD_HAVE_OPENSSL #include #endif @@ -14,16 +15,18 @@ namespace td { void MutableSlice::fill(char c) { std::memset(data(), c, size()); } + void MutableSlice::fill_zero() { - fill(0); + fill('\0'); } + void MutableSlice::fill_zero_secure() { #if TD_HAVE_OPENSSL OPENSSL_cleanse(begin(), size()); #else volatile char *ptr = begin(); for (size_t i = 0; i < size(); i++) { - ptr[i] = 0; + ptr[i] = '\0'; } #endif } diff --git a/tdutils/td/utils/ThreadLocalStorage.h b/tdutils/td/utils/ThreadLocalStorage.h index 06ab5e0f..9f3933d1 100644 --- a/tdutils/td/utils/ThreadLocalStorage.h +++ b/tdutils/td/utils/ThreadLocalStorage.h @@ -6,14 +6,13 @@ // #pragma once -#include "td/utils/port/thread.h" #include "td/utils/port/thread_local.h" -#include "td/utils/int_types.h" -#include #include +#include namespace td { + template class ThreadLocalStorage { public: @@ -23,15 +22,15 @@ class ThreadLocalStorage { template void for_each(F&& f) { - int n = max_thread_id_.load(); - for (int i = 0; i < n; i++) { + int32 n = max_thread_id_.load(); + for (int32 i = 0; i < n; i++) { f(nodes_[i].value); } } template void for_each(F&& f) const { - int n = max_thread_id_.load(); - for (int i = 0; i < n; i++) { + int32 n = max_thread_id_.load(); + for (int32 i = 0; i < n; i++) { f(nodes_[i].value); } } @@ -39,10 +38,10 @@ class ThreadLocalStorage { private: struct Node { T value{}; - char padding[128]; + char padding[TD_CONCURRENCY_PAD]; }; - static constexpr int MAX_THREAD_ID = 128; - std::atomic max_thread_id_{MAX_THREAD_ID}; + static constexpr int32 MAX_THREAD_ID = 128; + std::atomic max_thread_id_{MAX_THREAD_ID}; std::array nodes_; Node& thread_local_node() { @@ -51,4 +50,5 @@ class ThreadLocalStorage { return nodes_[thread_id]; } }; + } // namespace td diff --git a/tdutils/td/utils/ThreadSafeCounter.h b/tdutils/td/utils/ThreadSafeCounter.h index c1fd3c75..7df69398 100644 --- a/tdutils/td/utils/ThreadSafeCounter.h +++ b/tdutils/td/utils/ThreadSafeCounter.h @@ -5,13 +5,15 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/utils/ThreadLocalStorage.h" + #include "td/utils/StringBuilder.h" +#include "td/utils/ThreadLocalStorage.h" #include #include namespace td { + template class ThreadSafeMultiCounter { public: @@ -23,7 +25,7 @@ class ThreadSafeMultiCounter { int64 sum(size_t index) const { CHECK(index < N); int64 res = 0; - tls_.for_each([&](auto &value) { res += value[index].load(); }); + tls_.for_each([&](auto &value) { res += value[index].load(std::memory_order_relaxed); }); return res; } @@ -75,7 +77,7 @@ class NamedThreadSafeCounter { } } CHECK(names_.size() < N); - names_.push_back(name.str()); + names_.emplase_back(name.begin(), name.size()); return get_counter_ref(names_.size() - 1); } diff --git a/tdutils/td/utils/TsFileLog.cpp b/tdutils/td/utils/TsFileLog.cpp index 57aac34b..d5cf7e1c 100644 --- a/tdutils/td/utils/TsFileLog.cpp +++ b/tdutils/td/utils/TsFileLog.cpp @@ -4,15 +4,21 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "TsFileLog.h" +#include "td/utils/TsFileLog.h" + +#include "td/utils/logging.h" + +#include namespace td { + namespace detail { -class TsFileLog : public LogInterface { + +class TsFileLogImpl : public LogInterface { public: Status init(string path) { path_ = std::move(path); - for (int i = 0; i < (int)logs_.size(); i++) { + for (int32 i = 0; i < static_cast(logs_.size()); i++) { logs_[i].id = i; } return init_info(&logs_[0]); @@ -36,17 +42,17 @@ class TsFileLog : public LogInterface { private: struct Info { FileLog log; - bool is_inited; - int id; + bool is_inited = false; + int32 id; }; - static constexpr int MAX_THREAD_ID = 128; + static constexpr int32 MAX_THREAD_ID = 128; std::string path_; std::array logs_; LogInterface *get_current_logger() { auto *info = get_current_info(); if (!info->is_inited) { - CHECK(init_info(info).is_ok()); + init_info(info).ensure(); } return &info->log; } @@ -61,18 +67,20 @@ class TsFileLog : public LogInterface { return Status::OK(); } - string get_path(Info *info) { + string get_path(const Info *info) { if (info->id == 0) { return path_; } return PSTRING() << path_ << "." << info->id; } }; + } // namespace detail -Result> TsFileLog::create(string path) { - auto res = td::make_unique(); +Result> TsFileLog::create(string path) { + auto res = make_unique(); TRY_STATUS(res->init(path)); return std::move(res); } + } // namespace td diff --git a/tdutils/td/utils/TsFileLog.h b/tdutils/td/utils/TsFileLog.h index ac6aa1b6..bc0e2f4b 100644 --- a/tdutils/td/utils/TsFileLog.h +++ b/tdutils/td/utils/TsFileLog.h @@ -6,11 +6,16 @@ // #pragma once +#include "td/utils/common.h" #include "td/utils/FileLog.h" +#include "td/utils/logging.h" +#include "td/utils/Status.h" namespace td { + class TsFileLog { public: - static Result> create(string path); + static Result> create(string path); }; + } // namespace td diff --git a/tdutils/td/utils/base64.cpp b/tdutils/td/utils/base64.cpp index ba0562e9..b52a10d8 100644 --- a/tdutils/td/utils/base64.cpp +++ b/tdutils/td/utils/base64.cpp @@ -7,11 +7,10 @@ #include "td/utils/base64.h" #include "td/utils/common.h" +#include "td/utils/format.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" -#include "td/utils/format.h" - #include #include @@ -110,8 +109,7 @@ Status base64_do_decode(Slice base64, F &&append) { Result base64_decode(Slice base64) { init_base64_table(); - TRY_RESULT(tmp, base64_drop_padding(base64)); - base64 = tmp; + TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); string output; output.reserve(((base64.size() + 3) >> 2) * 3); @@ -122,8 +120,7 @@ Result base64_decode(Slice base64) { Result base64_decode_secure(Slice base64) { init_base64_table(); - TRY_RESULT(tmp, base64_drop_padding(base64)); - base64 = tmp; + TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64)); SecureString output(((base64.size() + 3) >> 2) * 3); char *ptr = output.as_mutable_slice().begin(); diff --git a/tdutils/td/utils/base64.h b/tdutils/td/utils/base64.h index d4ed52c1..bdaf8746 100644 --- a/tdutils/td/utils/base64.h +++ b/tdutils/td/utils/base64.h @@ -7,8 +7,8 @@ #pragma once #include "td/utils/common.h" -#include "td/utils/Slice.h" #include "td/utils/SharedSlice.h" +#include "td/utils/Slice.h" #include "td/utils/Status.h" namespace td { diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp index 2490bb34..9d11e244 100644 --- a/tdutils/td/utils/crypto.cpp +++ b/tdutils/td/utils/crypto.cpp @@ -308,7 +308,7 @@ class AesCtrState::Impl { if (AES_set_encrypt_key(key.ubegin(), 256, &aes_key) < 0) { LOG(FATAL) << "Failed to set encrypt key"; } - counter.as_mutable_slice().copy_from(as_slice(iv)); + counter.as_mutable_slice().copy_from(iv); current_pos = 0; } diff --git a/tdutils/td/utils/crypto.h b/tdutils/td/utils/crypto.h index 8edcb9dd..e5b79602 100644 --- a/tdutils/td/utils/crypto.h +++ b/tdutils/td/utils/crypto.h @@ -8,8 +8,8 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" -#include "td/utils/Slice.h" #include "td/utils/SharedSlice.h" +#include "td/utils/Slice.h" #include "td/utils/Status.h" namespace td { diff --git a/tdutils/td/utils/filesystem.h b/tdutils/td/utils/filesystem.h index 182a4e62..8522a3bb 100644 --- a/tdutils/td/utils/filesystem.h +++ b/tdutils/td/utils/filesystem.h @@ -7,15 +7,15 @@ #pragma once #include "td/utils/buffer.h" -#include "td/utils/Slice.h" #include "td/utils/SharedSlice.h" +#include "td/utils/Slice.h" #include "td/utils/Status.h" namespace td { Result read_file(CSlice path, int64 size = -1, int64 offset = 0); -Result read_file_str(CSlice path, int64 size = -1, int64 offset = 0); Result read_file_secure(CSlice path, int64 size = -1, int64 offset = 0); +Result read_file_str(CSlice path, int64 size = -1, int64 offset = 0); Status copy_file(CSlice from, CSlice to, int64 size = -1) TD_WARN_UNUSED_RESULT; diff --git a/tdutils/td/utils/tl_helpers.h b/tdutils/td/utils/tl_helpers.h index 2c7b2a3f..f04fdd30 100644 --- a/tdutils/td/utils/tl_helpers.h +++ b/tdutils/td/utils/tl_helpers.h @@ -9,8 +9,8 @@ #include "td/utils/common.h" #include "td/utils/logging.h" #include "td/utils/misc.h" -#include "td/utils/Slice.h" #include "td/utils/SharedSlice.h" +#include "td/utils/Slice.h" #include "td/utils/StackAllocator.h" #include "td/utils/Status.h" #include "td/utils/tl_parsers.h" diff --git a/tdutils/td/utils/tl_parsers.h b/tdutils/td/utils/tl_parsers.h index 15f6d1ac..1a672225 100644 --- a/tdutils/td/utils/tl_parsers.h +++ b/tdutils/td/utils/tl_parsers.h @@ -156,12 +156,14 @@ class TlParser { data += sizeof(int32); } else { check_len(sizeof(int32)); - result_len = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) + (static_cast(data[5]) << 32) + - (static_cast(data[6]) << 40) + (static_cast(data[7]) << 48); - if (result_len > std::numeric_limits::max() - 3) { + auto result_len_uint64 = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) + + (static_cast(data[5]) << 32) + (static_cast(data[6]) << 40) + + (static_cast(data[7]) << 48); + if (result_len_uint64 > std::numeric_limits::max() - 3) { set_error("Too big string found"); return T(); } + result_len = static_cast(result_len_uint64); result_begin = reinterpret_cast(data + 8); result_aligned_len = ((result_len + 3) >> 2) << 2; data += sizeof(int64); diff --git a/tdutils/td/utils/tl_storers.h b/tdutils/td/utils/tl_storers.h index 7c22d741..b2cb5841 100644 --- a/tdutils/td/utils/tl_storers.h +++ b/tdutils/td/utils/tl_storers.h @@ -83,7 +83,7 @@ class TlStorerUnsafe { // fallthrough case 2: *buf_++ = 0; - // fallthrough + // fallthrough case 3: *buf_++ = 0; } diff --git a/tdutils/test/SharedSlice.cpp b/tdutils/test/SharedSlice.cpp index 67ff1d88..d7678373 100644 --- a/tdutils/test/SharedSlice.cpp +++ b/tdutils/test/SharedSlice.cpp @@ -4,66 +4,65 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "td/utils/tests.h" #include "td/utils/SharedSlice.h" - -using namespace td; +#include "td/utils/tests.h" TEST(SharedSlice, Hands) { { - SharedSlice h("hello"); + td::SharedSlice h("hello"); ASSERT_EQ("hello", h.as_slice()); // auto g = h; // CE auto g = h.clone(); + ASSERT_EQ("hello", h.as_slice()); ASSERT_EQ("hello", g.as_slice()); } { - SharedSlice h("hello"); - UniqueSharedSlice g(std::move(h)); + td::SharedSlice h("hello"); + td::UniqueSharedSlice g(std::move(h)); ASSERT_EQ("", h.as_slice()); ASSERT_EQ("hello", g.as_slice()); } { - SharedSlice h("hello"); - SharedSlice t = h.clone(); - UniqueSharedSlice g(std::move(h)); + td::SharedSlice h("hello"); + td::SharedSlice t = h.clone(); + td::UniqueSharedSlice g(std::move(h)); ASSERT_EQ("", h.as_slice()); ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", t.as_slice()); } { - UniqueSharedSlice g(5); + td::UniqueSharedSlice g(5); g.as_mutable_slice().copy_from("hello"); - SharedSlice h(std::move(g)); + td::SharedSlice h(std::move(g)); ASSERT_EQ("hello", h); ASSERT_EQ("", g); } { - UniqueSlice h("hello"); - UniqueSlice g(std::move(h)); + td::UniqueSlice h("hello"); + td::UniqueSlice g(std::move(h)); ASSERT_EQ("", h.as_slice()); ASSERT_EQ("hello", g.as_slice()); } { - SecureString h("hello"); - SecureString g(std::move(h)); + td::SecureString h("hello"); + td::SecureString g(std::move(h)); ASSERT_EQ("", h.as_slice()); ASSERT_EQ("hello", g.as_slice()); } { - Stage stage; - SharedSlice a, b; - std::vector threads(2); + td::Stage stage; + td::SharedSlice a, b; + td::vector threads(2); for (int i = 0; i < 2; i++) { threads[i] = td::thread([i, &stage, &a, &b] { for (int j = 0; j < 10000; j++) { if (i == 0) { - a = SharedSlice("hello"); + a = td::SharedSlice("hello"); b = a.clone(); } stage.wait((2 * j + 1) * 2); @@ -71,7 +70,7 @@ TEST(SharedSlice, Hands) { ASSERT_EQ('h', a[0]); a.clear(); } else { - UniqueSharedSlice c(std::move(b)); + td::UniqueSharedSlice c(std::move(b)); c.as_mutable_slice()[0] = '!'; } stage.wait((2 * j + 2) * 2); diff --git a/tdutils/test/log.cpp b/tdutils/test/log.cpp index 990a4514..2836761a 100644 --- a/tdutils/test/log.cpp +++ b/tdutils/test/log.cpp @@ -4,23 +4,22 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "td/utils/tests.h" +#include "td/utils/benchmark.h" #include "td/utils/FileLog.h" -#include "td/utils/TsFileLog.h" #include "td/utils/logging.h" #include "td/utils/port/path.h" -#include "td/utils/benchmark.h" +#include "td/utils/tests.h" +#include "td/utils/TsFileLog.h" // Thread safe logging with tests // // LOG uses thread local LogInterface // void append(CSlice slice, int log_level); -// template class LogBenchmark : public td::Benchmark { public: - explicit LogBenchmark(std::string name, int threads_n, std::function()> creator) + LogBenchmark(std::string name, int threads_n, std::function()> creator) : name_(std::move(name)), threads_n_(threads_n), creator_(std::move(creator)) { } std::string get_description() const override {