Fix tdutils after merge.

GitOrigin-RevId: 3eceb2e574a737a78dc5414e535e416c86d23f7a
This commit is contained in:
levlam 2019-08-13 23:52:54 +03:00
parent c99486e667
commit bb24ec0629
21 changed files with 106 additions and 92 deletions

View File

@ -331,16 +331,15 @@ Result<size_t> FileDownloader::process_part(Part part, NetQueryPtr net_query) {
// Encryption // Encryption
if (need_cdn_decrypt) { if (need_cdn_decrypt) {
UInt128 iv = as<UInt128>(cdn_encryption_iv_.c_str());
CHECK(part.offset % 16 == 0); CHECK(part.offset % 16 == 0);
auto offset = narrow_cast<uint32>(part.offset / 16); auto offset = narrow_cast<uint32>(part.offset / 16);
offset = offset =
((offset & 0xff) << 24) | ((offset & 0xff00) << 8) | ((offset & 0xff0000) >> 8) | ((offset & 0xff000000) >> 24); ((offset & 0xff) << 24) | ((offset & 0xff00) << 8) | ((offset & 0xff0000) >> 8) | ((offset & 0xff000000) >> 24);
as<uint32>(iv.raw + 12) = offset;
UInt256 key = as<UInt256>(cdn_encryption_key_.c_str());
AesCtrState ctr_state; AesCtrState ctr_state;
ctr_state.init(as_slice(key), as_slice(iv)); string iv = cdn_encryption_iv_;
as<uint32>(&iv[12]) = offset;
ctr_state.init(cdn_encryption_key_, iv);
ctr_state.decrypt(bytes.as_slice(), bytes.as_slice()); ctr_state.decrypt(bytes.as_slice(), bytes.as_slice());
} }
if (encryption_key_.is_secret()) { if (encryption_key_.is_secret()) {

View File

@ -481,7 +481,7 @@ class XContext : public ActorContext {
int x = 1234; int x = 1234;
}; };
class WithContext : public Actor { class WithXContext : public Actor {
public: public:
void start_up() override { void start_up() override {
set_context(std::make_shared<XContext>()); set_context(std::make_shared<XContext>());
@ -491,8 +491,6 @@ class WithContext : public Actor {
void close() { void close() {
stop(); stop();
} }
private:
}; };
void check_context() { void check_context() {
@ -510,11 +508,11 @@ TEST(Actors, context_during_destruction) {
{ {
auto guard = sched.get_main_guard(); auto guard = sched.get_main_guard();
auto with_context = create_actor<WithContext>("WithContext").release(); auto with_context = create_actor<WithXContext>("WithXContext").release();
send_closure(with_context, &WithContext::f, create_lambda_guard([] { check_context(); })); send_closure(with_context, &WithXContext::f, create_lambda_guard([] { check_context(); }));
send_closure_later(with_context, &WithContext::close); send_closure_later(with_context, &WithXContext::close);
send_closure(with_context, &WithContext::f, create_lambda_guard([] { check_context(); })); send_closure(with_context, &WithXContext::f, create_lambda_guard([] { check_context(); }));
send_closure(with_context, &WithContext::f, create_lambda_guard([] { Scheduler::instance()->finish(); })); send_closure(with_context, &WithXContext::f, create_lambda_guard([] { Scheduler::instance()->finish(); }));
} }
sched.start(); sched.start();
while (sched.run_main(10)) { while (sched.run_main(10)) {

View File

@ -99,17 +99,17 @@ set(TDUTILS_SOURCE
td/utils/MpmcQueue.cpp td/utils/MpmcQueue.cpp
td/utils/OptionsParser.cpp td/utils/OptionsParser.cpp
td/utils/Random.cpp td/utils/Random.cpp
td/utils/Slice.cpp
td/utils/SharedSlice.cpp td/utils/SharedSlice.cpp
td/utils/Slice.cpp
td/utils/StackAllocator.cpp td/utils/StackAllocator.cpp
td/utils/Status.cpp td/utils/Status.cpp
td/utils/StringBuilder.cpp td/utils/StringBuilder.cpp
td/utils/tests.cpp
td/utils/Time.cpp td/utils/Time.cpp
td/utils/Timer.cpp td/utils/Timer.cpp
td/utils/TsFileLog.cpp
td/utils/tests.cpp
td/utils/tl_parsers.cpp td/utils/tl_parsers.cpp
td/utils/translit.cpp td/utils/translit.cpp
td/utils/TsFileLog.cpp
td/utils/unicode.cpp td/utils/unicode.cpp
td/utils/utf8.cpp td/utils/utf8.cpp
@ -220,6 +220,7 @@ set(TDUTILS_SOURCE
td/utils/Random.h td/utils/Random.h
td/utils/ScopeGuard.h td/utils/ScopeGuard.h
td/utils/SharedObjectPool.h td/utils/SharedObjectPool.h
td/utils/SharedSlice.h
td/utils/Slice-decl.h td/utils/Slice-decl.h
td/utils/Slice.h td/utils/Slice.h
td/utils/Span.h td/utils/Span.h
@ -230,15 +231,16 @@ set(TDUTILS_SOURCE
td/utils/StorerBase.h td/utils/StorerBase.h
td/utils/StringBuilder.h td/utils/StringBuilder.h
td/utils/tests.h td/utils/tests.h
td/utils/ThreadLocalStorage.h
td/utils/ThreadSafeCounter.h td/utils/ThreadSafeCounter.h
td/utils/Time.h td/utils/Time.h
td/utils/TimedStat.h td/utils/TimedStat.h
td/utils/Timer.h td/utils/Timer.h
td/utils/TsFileLog.h
td/utils/tl_helpers.h td/utils/tl_helpers.h
td/utils/tl_parsers.h td/utils/tl_parsers.h
td/utils/tl_storers.h td/utils/tl_storers.h
td/utils/translit.h td/utils/translit.h
td/utils/TsFileLog.h
td/utils/type_traits.h td/utils/type_traits.h
td/utils/UInt.h td/utils/UInt.h
td/utils/uint128.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/ConcurrentHashMap.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/EpochBasedMemoryReclamation.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

View File

@ -37,7 +37,7 @@ class FileLog : public LogInterface {
string path_; string path_;
int64 size_ = 0; int64 size_ = 0;
int64 rotate_threshold_ = 0; int64 rotate_threshold_ = 0;
bool redirect_stderr_; bool redirect_stderr_ = false;
void do_rotate(); void do_rotate();
}; };

View File

@ -11,7 +11,7 @@
namespace td { namespace td {
BufferSlice SharedSlice::clone_as_buffer_slice() const { BufferSlice SharedSlice::clone_as_buffer_slice() const {
return BufferSlice{as_slice().str()}; return BufferSlice{as_slice()};
} }
} // namespace td } // namespace td

View File

@ -15,7 +15,7 @@ namespace td {
namespace detail { namespace detail {
struct SharedSliceHeader { struct SharedSliceHeader {
explicit SharedSliceHeader(size_t size) : refcnt_{1}, size_{size} { explicit SharedSliceHeader(size_t size) : size_{size} {
} }
void inc() { void inc() {
@ -37,7 +37,7 @@ struct SharedSliceHeader {
} }
private: private:
std::atomic<uint64> refcnt_; std::atomic<uint64> refcnt_{1};
size_t size_; size_t size_;
}; };
@ -107,9 +107,9 @@ class UnsafeSharedSlice {
static UnsafeSharedSlice create(size_t size) { static UnsafeSharedSlice create(size_t size) {
static_assert(std::is_standard_layout<HeaderT>::value, "HeaderT must have statdard layout"); static_assert(std::is_standard_layout<HeaderT>::value, "HeaderT must have statdard layout");
auto ptr = std::make_unique<char[]>(size + sizeof(HeaderT)); auto ptr = std::make_unique<char[]>(sizeof(HeaderT) + size);
auto header_ptr = new (ptr.get()) HeaderT(size); auto header_ptr = new (ptr.get()) HeaderT(size);
CHECK(reinterpret_cast<char *>(header_ptr) == ptr.get()); CHECK(header_ptr == reinterpret_cast<HeaderT *>(ptr.get()));
return UnsafeSharedSlice(std::move(ptr)); return UnsafeSharedSlice(std::move(ptr));
} }
@ -160,8 +160,7 @@ class SharedSlice {
public: public:
SharedSlice() = default; SharedSlice() = default;
explicit SharedSlice(Slice slice) : impl_(Impl::create(slice.size())) { explicit SharedSlice(Slice slice) : impl_(Impl::create(slice)) {
impl_.as_mutable_slice().copy_from(slice);
} }
explicit SharedSlice(UniqueSharedSlice from); explicit SharedSlice(UniqueSharedSlice from);
@ -301,7 +300,7 @@ class UniqueSliceImpl {
explicit UniqueSliceImpl(size_t size) : impl_(Impl::create(size)) { explicit UniqueSliceImpl(size_t size) : impl_(Impl::create(size)) {
} }
UniqueSliceImpl(size_t size, char c) : 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)) { explicit UniqueSliceImpl(Slice slice) : impl_(Impl::create(slice)) {
} }

View File

@ -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)
// //
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#if TD_HAVE_OPENSSL #if TD_HAVE_OPENSSL
#include <openssl/crypto.h> #include <openssl/crypto.h>
#endif #endif
@ -14,16 +15,18 @@ namespace td {
void MutableSlice::fill(char c) { void MutableSlice::fill(char c) {
std::memset(data(), c, size()); std::memset(data(), c, size());
} }
void MutableSlice::fill_zero() { void MutableSlice::fill_zero() {
fill(0); fill('\0');
} }
void MutableSlice::fill_zero_secure() { void MutableSlice::fill_zero_secure() {
#if TD_HAVE_OPENSSL #if TD_HAVE_OPENSSL
OPENSSL_cleanse(begin(), size()); OPENSSL_cleanse(begin(), size());
#else #else
volatile char *ptr = begin(); volatile char *ptr = begin();
for (size_t i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
ptr[i] = 0; ptr[i] = '\0';
} }
#endif #endif
} }

View File

@ -6,14 +6,13 @@
// //
#pragma once #pragma once
#include "td/utils/port/thread.h"
#include "td/utils/port/thread_local.h" #include "td/utils/port/thread_local.h"
#include "td/utils/int_types.h"
#include <atomic>
#include <array> #include <array>
#include <atomic>
namespace td { namespace td {
template <class T> template <class T>
class ThreadLocalStorage { class ThreadLocalStorage {
public: public:
@ -23,15 +22,15 @@ class ThreadLocalStorage {
template <class F> template <class F>
void for_each(F&& f) { void for_each(F&& f) {
int n = max_thread_id_.load(); int32 n = max_thread_id_.load();
for (int i = 0; i < n; i++) { for (int32 i = 0; i < n; i++) {
f(nodes_[i].value); f(nodes_[i].value);
} }
} }
template <class F> template <class F>
void for_each(F&& f) const { void for_each(F&& f) const {
int n = max_thread_id_.load(); int32 n = max_thread_id_.load();
for (int i = 0; i < n; i++) { for (int32 i = 0; i < n; i++) {
f(nodes_[i].value); f(nodes_[i].value);
} }
} }
@ -39,10 +38,10 @@ class ThreadLocalStorage {
private: private:
struct Node { struct Node {
T value{}; T value{};
char padding[128]; char padding[TD_CONCURRENCY_PAD];
}; };
static constexpr int MAX_THREAD_ID = 128; static constexpr int32 MAX_THREAD_ID = 128;
std::atomic<int> max_thread_id_{MAX_THREAD_ID}; std::atomic<int32> max_thread_id_{MAX_THREAD_ID};
std::array<Node, MAX_THREAD_ID> nodes_; std::array<Node, MAX_THREAD_ID> nodes_;
Node& thread_local_node() { Node& thread_local_node() {
@ -51,4 +50,5 @@ class ThreadLocalStorage {
return nodes_[thread_id]; return nodes_[thread_id];
} }
}; };
} // namespace td } // namespace td

View File

@ -5,13 +5,15 @@
// 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/ThreadLocalStorage.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include "td/utils/ThreadLocalStorage.h"
#include <array> #include <array>
#include <mutex> #include <mutex>
namespace td { namespace td {
template <size_t N> template <size_t N>
class ThreadSafeMultiCounter { class ThreadSafeMultiCounter {
public: public:
@ -23,7 +25,7 @@ class ThreadSafeMultiCounter {
int64 sum(size_t index) const { int64 sum(size_t index) const {
CHECK(index < N); CHECK(index < N);
int64 res = 0; 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; return res;
} }
@ -75,7 +77,7 @@ class NamedThreadSafeCounter {
} }
} }
CHECK(names_.size() < N); CHECK(names_.size() < N);
names_.push_back(name.str()); names_.emplase_back(name.begin(), name.size());
return get_counter_ref(names_.size() - 1); return get_counter_ref(names_.size() - 1);
} }

View File

@ -4,15 +4,21 @@
// 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 "TsFileLog.h" #include "td/utils/TsFileLog.h"
#include "td/utils/logging.h"
#include <array>
namespace td { namespace td {
namespace detail { namespace detail {
class TsFileLog : public LogInterface {
class TsFileLogImpl : public LogInterface {
public: public:
Status init(string path) { Status init(string path) {
path_ = std::move(path); path_ = std::move(path);
for (int i = 0; i < (int)logs_.size(); i++) { for (int32 i = 0; i < static_cast<int32>(logs_.size()); i++) {
logs_[i].id = i; logs_[i].id = i;
} }
return init_info(&logs_[0]); return init_info(&logs_[0]);
@ -36,17 +42,17 @@ class TsFileLog : public LogInterface {
private: private:
struct Info { struct Info {
FileLog log; FileLog log;
bool is_inited; bool is_inited = false;
int id; int32 id;
}; };
static constexpr int MAX_THREAD_ID = 128; static constexpr int32 MAX_THREAD_ID = 128;
std::string path_; std::string path_;
std::array<Info, MAX_THREAD_ID> logs_; std::array<Info, MAX_THREAD_ID> logs_;
LogInterface *get_current_logger() { LogInterface *get_current_logger() {
auto *info = get_current_info(); auto *info = get_current_info();
if (!info->is_inited) { if (!info->is_inited) {
CHECK(init_info(info).is_ok()); init_info(info).ensure();
} }
return &info->log; return &info->log;
} }
@ -61,18 +67,20 @@ class TsFileLog : public LogInterface {
return Status::OK(); return Status::OK();
} }
string get_path(Info *info) { string get_path(const Info *info) {
if (info->id == 0) { if (info->id == 0) {
return path_; return path_;
} }
return PSTRING() << path_ << "." << info->id; return PSTRING() << path_ << "." << info->id;
} }
}; };
} // namespace detail } // namespace detail
Result<td::unique_ptr<LogInterface>> TsFileLog::create(string path) { Result<unique_ptr<LogInterface>> TsFileLog::create(string path) {
auto res = td::make_unique<detail::TsFileLog>(); auto res = make_unique<detail::TsFileLogImpl>();
TRY_STATUS(res->init(path)); TRY_STATUS(res->init(path));
return std::move(res); return std::move(res);
} }
} // namespace td } // namespace td

View File

@ -6,11 +6,16 @@
// //
#pragma once #pragma once
#include "td/utils/common.h"
#include "td/utils/FileLog.h" #include "td/utils/FileLog.h"
#include "td/utils/logging.h"
#include "td/utils/Status.h"
namespace td { namespace td {
class TsFileLog { class TsFileLog {
public: public:
static Result<td::unique_ptr<LogInterface>> create(string path); static Result<unique_ptr<LogInterface>> create(string path);
}; };
} // namespace td } // namespace td

View File

@ -7,11 +7,10 @@
#include "td/utils/base64.h" #include "td/utils/base64.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/format.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/format.h"
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
@ -110,8 +109,7 @@ Status base64_do_decode(Slice base64, F &&append) {
Result<string> base64_decode(Slice base64) { Result<string> base64_decode(Slice base64) {
init_base64_table(); init_base64_table();
TRY_RESULT(tmp, base64_drop_padding(base64)); TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64));
base64 = tmp;
string output; string output;
output.reserve(((base64.size() + 3) >> 2) * 3); output.reserve(((base64.size() + 3) >> 2) * 3);
@ -122,8 +120,7 @@ Result<string> base64_decode(Slice base64) {
Result<SecureString> base64_decode_secure(Slice base64) { Result<SecureString> base64_decode_secure(Slice base64) {
init_base64_table(); init_base64_table();
TRY_RESULT(tmp, base64_drop_padding(base64)); TRY_RESULT_ASSIGN(base64, base64_drop_padding(base64));
base64 = tmp;
SecureString output(((base64.size() + 3) >> 2) * 3); SecureString output(((base64.size() + 3) >> 2) * 3);
char *ptr = output.as_mutable_slice().begin(); char *ptr = output.as_mutable_slice().begin();

View File

@ -7,8 +7,8 @@
#pragma once #pragma once
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Slice.h"
#include "td/utils/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
namespace td { namespace td {

View File

@ -308,7 +308,7 @@ class AesCtrState::Impl {
if (AES_set_encrypt_key(key.ubegin(), 256, &aes_key) < 0) { if (AES_set_encrypt_key(key.ubegin(), 256, &aes_key) < 0) {
LOG(FATAL) << "Failed to set encrypt key"; 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; current_pos = 0;
} }

View File

@ -8,8 +8,8 @@
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Slice.h"
#include "td/utils/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
namespace td { namespace td {

View File

@ -7,15 +7,15 @@
#pragma once #pragma once
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/Slice.h"
#include "td/utils/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
namespace td { namespace td {
Result<BufferSlice> read_file(CSlice path, int64 size = -1, int64 offset = 0); Result<BufferSlice> read_file(CSlice path, int64 size = -1, int64 offset = 0);
Result<string> read_file_str(CSlice path, int64 size = -1, int64 offset = 0);
Result<SecureString> read_file_secure(CSlice path, int64 size = -1, int64 offset = 0); Result<SecureString> read_file_secure(CSlice path, int64 size = -1, int64 offset = 0);
Result<string> 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; Status copy_file(CSlice from, CSlice to, int64 size = -1) TD_WARN_UNUSED_RESULT;

View File

@ -9,8 +9,8 @@
#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/Slice.h"
#include "td/utils/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
#include "td/utils/StackAllocator.h" #include "td/utils/StackAllocator.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/tl_parsers.h" #include "td/utils/tl_parsers.h"

View File

@ -156,12 +156,14 @@ class TlParser {
data += sizeof(int32); data += sizeof(int32);
} else { } else {
check_len(sizeof(int32)); check_len(sizeof(int32));
result_len = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) + (static_cast<uint64>(data[5]) << 32) + auto result_len_uint64 = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24) +
(static_cast<uint64>(data[6]) << 40) + (static_cast<uint64>(data[7]) << 48); (static_cast<uint64>(data[5]) << 32) + (static_cast<uint64>(data[6]) << 40) +
if (result_len > std::numeric_limits<size_t>::max() - 3) { (static_cast<uint64>(data[7]) << 48);
if (result_len_uint64 > std::numeric_limits<size_t>::max() - 3) {
set_error("Too big string found"); set_error("Too big string found");
return T(); return T();
} }
result_len = static_cast<size_t>(result_len_uint64);
result_begin = reinterpret_cast<const char *>(data + 8); result_begin = reinterpret_cast<const char *>(data + 8);
result_aligned_len = ((result_len + 3) >> 2) << 2; result_aligned_len = ((result_len + 3) >> 2) << 2;
data += sizeof(int64); data += sizeof(int64);

View File

@ -83,7 +83,7 @@ class TlStorerUnsafe {
// fallthrough // fallthrough
case 2: case 2:
*buf_++ = 0; *buf_++ = 0;
// fallthrough // fallthrough
case 3: case 3:
*buf_++ = 0; *buf_++ = 0;
} }

View File

@ -4,66 +4,65 @@
// 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/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/tests.h"
using namespace td;
TEST(SharedSlice, Hands) { TEST(SharedSlice, Hands) {
{ {
SharedSlice h("hello"); td::SharedSlice h("hello");
ASSERT_EQ("hello", h.as_slice()); ASSERT_EQ("hello", h.as_slice());
// auto g = h; // CE // auto g = h; // CE
auto g = h.clone(); auto g = h.clone();
ASSERT_EQ("hello", h.as_slice());
ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", g.as_slice());
} }
{ {
SharedSlice h("hello"); td::SharedSlice h("hello");
UniqueSharedSlice g(std::move(h)); td::UniqueSharedSlice g(std::move(h));
ASSERT_EQ("", h.as_slice()); ASSERT_EQ("", h.as_slice());
ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", g.as_slice());
} }
{ {
SharedSlice h("hello"); td::SharedSlice h("hello");
SharedSlice t = h.clone(); td::SharedSlice t = h.clone();
UniqueSharedSlice g(std::move(h)); td::UniqueSharedSlice g(std::move(h));
ASSERT_EQ("", h.as_slice()); ASSERT_EQ("", h.as_slice());
ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", g.as_slice());
ASSERT_EQ("hello", t.as_slice()); ASSERT_EQ("hello", t.as_slice());
} }
{ {
UniqueSharedSlice g(5); td::UniqueSharedSlice g(5);
g.as_mutable_slice().copy_from("hello"); g.as_mutable_slice().copy_from("hello");
SharedSlice h(std::move(g)); td::SharedSlice h(std::move(g));
ASSERT_EQ("hello", h); ASSERT_EQ("hello", h);
ASSERT_EQ("", g); ASSERT_EQ("", g);
} }
{ {
UniqueSlice h("hello"); td::UniqueSlice h("hello");
UniqueSlice g(std::move(h)); td::UniqueSlice g(std::move(h));
ASSERT_EQ("", h.as_slice()); ASSERT_EQ("", h.as_slice());
ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", g.as_slice());
} }
{ {
SecureString h("hello"); td::SecureString h("hello");
SecureString g(std::move(h)); td::SecureString g(std::move(h));
ASSERT_EQ("", h.as_slice()); ASSERT_EQ("", h.as_slice());
ASSERT_EQ("hello", g.as_slice()); ASSERT_EQ("hello", g.as_slice());
} }
{ {
Stage stage; td::Stage stage;
SharedSlice a, b; td::SharedSlice a, b;
std::vector<td::thread> threads(2); td::vector<td::thread> threads(2);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
threads[i] = td::thread([i, &stage, &a, &b] { threads[i] = td::thread([i, &stage, &a, &b] {
for (int j = 0; j < 10000; j++) { for (int j = 0; j < 10000; j++) {
if (i == 0) { if (i == 0) {
a = SharedSlice("hello"); a = td::SharedSlice("hello");
b = a.clone(); b = a.clone();
} }
stage.wait((2 * j + 1) * 2); stage.wait((2 * j + 1) * 2);
@ -71,7 +70,7 @@ TEST(SharedSlice, Hands) {
ASSERT_EQ('h', a[0]); ASSERT_EQ('h', a[0]);
a.clear(); a.clear();
} else { } else {
UniqueSharedSlice c(std::move(b)); td::UniqueSharedSlice c(std::move(b));
c.as_mutable_slice()[0] = '!'; c.as_mutable_slice()[0] = '!';
} }
stage.wait((2 * j + 2) * 2); stage.wait((2 * j + 2) * 2);

View File

@ -4,23 +4,22 @@
// 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/benchmark.h"
#include "td/utils/FileLog.h" #include "td/utils/FileLog.h"
#include "td/utils/TsFileLog.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/port/path.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 // Thread safe logging with tests
// //
// LOG uses thread local LogInterface // LOG uses thread local LogInterface
// void append(CSlice slice, int log_level); // void append(CSlice slice, int log_level);
//
template <class Log> template <class Log>
class LogBenchmark : public td::Benchmark { class LogBenchmark : public td::Benchmark {
public: public:
explicit LogBenchmark(std::string name, int threads_n, std::function<td::unique_ptr<Log>()> creator) LogBenchmark(std::string name, int threads_n, std::function<td::unique_ptr<Log>()> creator)
: name_(std::move(name)), threads_n_(threads_n), creator_(std::move(creator)) { : name_(std::move(name)), threads_n_(threads_n), creator_(std::move(creator)) {
} }
std::string get_description() const override { std::string get_description() const override {