diff options
Diffstat (limited to 'libtransport/includes/hicn/transport/utils')
14 files changed, 446 insertions, 102 deletions
diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt index 11a9b0f25..7094601f4 100644 --- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt +++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt @@ -31,6 +31,11 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/fixed_block_allocator.h ${CMAKE_CURRENT_SOURCE_DIR}/event_thread.h ${CMAKE_CURRENT_SOURCE_DIR}/string_utils.h + ${CMAKE_CURRENT_SOURCE_DIR}/file.h + ${CMAKE_CURRENT_SOURCE_DIR}/shared_ptr_utils.h + ${CMAKE_CURRENT_SOURCE_DIR}/move_wrapper.h + ${CMAKE_CURRENT_SOURCE_DIR}/noncopyable.h + ${CMAKE_CURRENT_SOURCE_DIR}/singleton.h ) if(NOT WIN32) diff --git a/libtransport/includes/hicn/transport/utils/conversions.h b/libtransport/includes/hicn/transport/utils/conversions.h index 24b529206..52d3e3168 100644 --- a/libtransport/includes/hicn/transport/utils/conversions.h +++ b/libtransport/includes/hicn/transport/utils/conversions.h @@ -16,8 +16,8 @@ #pragma once #include <hicn/transport/portability/portability.h> - #include <stdio.h> + #include <cstdint> #include <string> diff --git a/libtransport/includes/hicn/transport/utils/enum_iterator.h b/libtransport/includes/hicn/transport/utils/enum_iterator.h new file mode 100644 index 000000000..5e108b088 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/enum_iterator.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <type_traits> + +template <typename C, C begin_val, C end_val> +class Iterator { + typedef typename std::underlying_type<C>::type val_t; + int val; + + public: + Iterator(const C& f) : val(static_cast<val_t>(f)) {} + + Iterator() : val(static_cast<val_t>(begin_val)) {} + + Iterator operator++() { + ++val; + return *this; + } + + C operator*() { return static_cast<C>(val); } + + Iterator begin() { return *this; } // default ctor is good + + Iterator end() { + static const Iterator endIter = ++Iterator(end_val); // cache it + return endIter; + } + + bool operator!=(const Iterator& i) { return val != i.val; } +};
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/event_thread.h b/libtransport/includes/hicn/transport/utils/event_thread.h index 702c98f8d..bb6ab90ef 100644 --- a/libtransport/includes/hicn/transport/utils/event_thread.h +++ b/libtransport/includes/hicn/transport/utils/event_thread.h @@ -17,7 +17,11 @@ #include <hicn/transport/config.h> #include <hicn/transport/errors/runtime_exception.h> +#include <hicn/transport/utils/log.h> +#ifndef ASIO_STANDALONE +#define ASIO_STANDALONE +#endif #include <asio.hpp> #include <memory> #include <thread> @@ -25,36 +29,58 @@ namespace utils { class EventThread { - private: - // No copies - EventThread(const EventThread&) = delete; // non construction-copyable - EventThread& operator=(const EventThread&) = delete; // non copyable - public: - explicit EventThread(asio::io_service& io_service) + EventThread(asio::io_service& io_service, bool detached = false) : internal_io_service_(nullptr), - io_service_(io_service), + io_service_(std::ref(io_service)), work_(std::make_unique<asio::io_service::work>(io_service_)), - thread_(nullptr) { + thread_(nullptr), + detached_(detached) { run(); } - explicit EventThread() + EventThread(bool detached = false) : internal_io_service_(std::make_unique<asio::io_service>()), - io_service_(*internal_io_service_), + io_service_(std::ref(*internal_io_service_)), work_(std::make_unique<asio::io_service::work>(io_service_)), - thread_(nullptr) { + thread_(nullptr), + detached_(detached) { run(); } + EventThread(const EventThread&) = delete; + EventThread& operator=(const EventThread&) = delete; + + EventThread(EventThread&& other) + : internal_io_service_(std::move(other.internal_io_service_)), + io_service_(std::move(other.io_service_)), + work_(std::move(other.work_)), + thread_(std::move(other.thread_)), + detached_(std::move(other.detached_)) {} + + EventThread& operator=(EventThread&& other) { + internal_io_service_ = std::move(other.internal_io_service_); + io_service_ = std::move(other.io_service_); + work_ = std::move(other.work_); + thread_ = std::move(other.thread_); + detached_ = other.detached_; + + return *this; + } + ~EventThread() { stop(); } void run() { if (stopped()) { - io_service_.reset(); + io_service_.get().stopped(); } - thread_ = std::make_unique<std::thread>([this]() { io_service_.run(); }); + thread_ = + std::make_unique<std::thread>([this]() { io_service_.get().run(); }); + + if (detached_) { + thread_->detach(); + } } std::thread::id getThreadId() const { @@ -67,14 +93,12 @@ class EventThread { template <typename Func> void add(Func&& f) { - // If the function f - // TODO USe post in mac os, asio->post in xenial - io_service_.post(std::forward<Func&&>(f)); + io_service_.get().post(std::forward<Func&&>(f)); } template <typename Func> void tryRunHandlerNow(Func&& f) { - io_service_.dispatch(std::forward<Func&&>(f)); + io_service_.get().dispatch(std::forward<Func&&>(f)); } void stop() { @@ -87,15 +111,16 @@ class EventThread { thread_.reset(); } - bool stopped() { return io_service_.stopped(); } + bool stopped() { return io_service_.get().stopped(); } asio::io_service& getIoService() { return io_service_; } private: std::unique_ptr<asio::io_service> internal_io_service_; - asio::io_service& io_service_; + std::reference_wrapper<asio::io_service> io_service_; std::unique_ptr<asio::io_service::work> work_; std::unique_ptr<std::thread> thread_; + bool detached_; }; } // namespace utils
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/file.h b/libtransport/includes/hicn/transport/utils/file.h new file mode 100644 index 000000000..4c73f33e8 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/file.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/stat.h> + +namespace utils { + +class File { + public: + static inline bool exists(const std::string& name) { + struct stat buffer; + return (stat(name.c_str(), &buffer) == 0); + } +}; + +} // namespace utils diff --git a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h index 1ade1516e..b1df36493 100644 --- a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h +++ b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h @@ -5,104 +5,99 @@ #pragma once #include <hicn/transport/portability/c_portability.h> +#include <hicn/transport/utils/singleton.h> #include <hicn/transport/utils/spinlock.h> - #include <stdint.h> + +#include <cassert> #include <cstdlib> #include <memory> -#include <cassert> namespace utils { -template <std::size_t DEFAULT_SIZE = 512, std::size_t OBJECTS = 4096> -class FixedBlockAllocator { - FixedBlockAllocator(std::size_t size = DEFAULT_SIZE, - std::size_t objects = OBJECTS) - : block_size_(size < sizeof(void*) ? sizeof(long*) : size), - object_size_(size), - max_objects_(objects), - p_head_(NULL), - pool_index_(0), - block_count_(0), - blocks_in_use_(0), - allocations_(0), - deallocations_(0) { - p_pool_ = (uint8_t*)new uint8_t[block_size_ * max_objects_]; - } +template <std::size_t SIZE = 512, std::size_t OBJECTS = 4096> +class FixedBlockAllocator + : public utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>> { + friend class utils::Singleton<FixedBlockAllocator<SIZE, OBJECTS>>; public: - static FixedBlockAllocator* getInstance() { - if (!instance_) { - instance_ = std::unique_ptr<FixedBlockAllocator>( - new FixedBlockAllocator(DEFAULT_SIZE, OBJECTS)); + ~FixedBlockAllocator() { + for (auto& p : p_pools_) { + delete[] p; } - - return instance_.get(); } - ~FixedBlockAllocator() { delete[] p_pool_; } - - TRANSPORT_ALWAYS_INLINE void* allocateBlock(size_t size = DEFAULT_SIZE) { - assert(size <= DEFAULT_SIZE); + void* allocateBlock(size_t size = SIZE) { + assert(size <= SIZE); uint32_t index; + SpinLock::Acquire locked(lock_); void* p_block = pop(); if (!p_block) { - if (pool_index_ < max_objects_) { - { - SpinLock::Acquire locked(lock_); - index = pool_index_++; - } - p_block = (void*)(p_pool_ + (index * block_size_)); - } else { - // TODO Consider increasing pool here instead of throwing an exception - throw std::runtime_error("No more memory available from packet pool!"); + if (TRANSPORT_EXPECT_FALSE(current_pool_index_ >= max_objects_)) { + // Allocate new memory block + TRANSPORT_LOGV("Allocating new block of %zu size", SIZE * OBJECTS); + p_pools_.emplace_front( + new typename std::aligned_storage<SIZE>::type[max_objects_]); + // reset current_pool_index_ + current_pool_index_ = 0; } - } - blocks_in_use_++; - allocations_++; + auto& latest = p_pools_.front(); + index = current_pool_index_++; + blocks_in_use_++; + allocations_++; + p_block = (void*)&latest[index]; + } return p_block; } - TRANSPORT_ALWAYS_INLINE void deallocateBlock(void* pBlock) { + void deallocateBlock(void* pBlock) { + SpinLock::Acquire locked(lock_); push(pBlock); - { - SpinLock::Acquire locked(lock_); - blocks_in_use_--; - deallocations_++; - } + blocks_in_use_--; + deallocations_++; } - TRANSPORT_ALWAYS_INLINE std::size_t blockSize() { return block_size_; } + public: + std::size_t blockSize() { return block_size_; } - TRANSPORT_ALWAYS_INLINE uint32_t blockCount() { return block_count_; } + uint32_t blockCount() { return block_count_; } - TRANSPORT_ALWAYS_INLINE uint32_t blocksInUse() { return blocks_in_use_; } + uint32_t blocksInUse() { return blocks_in_use_; } - TRANSPORT_ALWAYS_INLINE uint32_t allocations() { return allocations_; } + uint32_t allocations() { return allocations_; } - TRANSPORT_ALWAYS_INLINE uint32_t deallocations() { return deallocations_; } + uint32_t deallocations() { return deallocations_; } private: - TRANSPORT_ALWAYS_INLINE void push(void* p_memory) { + FixedBlockAllocator() + : block_size_(SIZE), + object_size_(SIZE), + max_objects_(OBJECTS), + p_head_(NULL), + current_pool_index_(0), + block_count_(0), + blocks_in_use_(0), + allocations_(0), + deallocations_(0) { + static_assert(SIZE >= sizeof(long*), "SIZE must be at least 8 bytes"); + p_pools_.emplace_front( + new typename std::aligned_storage<SIZE>::type[max_objects_]); + } + + void push(void* p_memory) { Block* p_block = (Block*)p_memory; - { - SpinLock::Acquire locked(lock_); - p_block->p_next = p_head_; - p_head_ = p_block; - } + p_block->p_next = p_head_; + p_head_ = p_block; } - TRANSPORT_ALWAYS_INLINE void* pop() { + void* pop() { Block* p_block = nullptr; - { - SpinLock::Acquire locked(lock_); - if (p_head_) { - p_block = p_head_; - p_head_ = p_head_->p_next; - } + if (p_head_) { + p_block = p_head_; + p_head_ = p_head_->p_next; } return (void*)p_block; @@ -119,8 +114,8 @@ class FixedBlockAllocator { const std::size_t max_objects_; Block* p_head_; - uint8_t* p_pool_; - uint32_t pool_index_; + uint32_t current_pool_index_; + std::list<typename std::aligned_storage<SIZE>::type*> p_pools_; uint32_t block_count_; uint32_t blocks_in_use_; uint32_t allocations_; @@ -133,4 +128,88 @@ template <std::size_t A, std::size_t B> std::unique_ptr<FixedBlockAllocator<A, B>> FixedBlockAllocator<A, B>::instance_ = nullptr; +/** + * STL Allocator trait to be used with allocate_shared. + */ +template <typename T, typename Pool> +class STLAllocator { + /** + * If STLAllocator is rebound to another type (!= T) using copy constructor, + * we may need to access private members of the source allocator to copy + * memory and pool. + */ + template <typename U, typename P> + friend class STLAllocator; + + public: + using size_type = std::size_t; + using difference_type = ptrdiff_t; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using value_type = T; + + STLAllocator(pointer memory, Pool* memory_pool) + : memory_(memory), pool_(memory_pool) { + TRANSPORT_LOGV("Creating allocator. This: %p, memory: %p, memory_pool: %p", + this, memory, memory_pool); + } + + ~STLAllocator() {} + + template <typename U> + STLAllocator(const STLAllocator<U, Pool>& other) { + memory_ = other.memory_; + pool_ = other.pool_; + } + + template <typename U> + struct rebind { + typedef STLAllocator<U, Pool> other; + }; + + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } + + pointer allocate(size_type n, pointer hint = 0) { + TRANSPORT_LOGV( + "Allocating memory (%zu). This: %p, memory: %p, memory_pool: %p", n, + this, memory_, pool_); + return static_cast<pointer>(memory_); + } + + void deallocate(pointer p, size_type n) { + TRANSPORT_LOGV("Deallocating memory. This: %p, memory: %p, memory_pool: %p", + this, memory_, pool_); + pool_->deallocateBlock(memory_); + } + + template <typename... Args> + void construct(pointer p, Args&&... args) { + new (static_cast<pointer>(p)) T(std::forward<Args>(args)...); + } + + void destroy(pointer p) { + TRANSPORT_LOGV("Destroying object. This: %p, memory: %p, memory_pool: %p", + this, memory_, pool_); + p->~T(); + } + + private: + void* memory_; + Pool* pool_; +}; + +template <typename T, typename U, typename V> +inline bool operator==(const STLAllocator<T, V>&, const STLAllocator<U, V>&) { + return true; +} + +template <typename T, typename U, typename V> +inline bool operator!=(const STLAllocator<T, V>& a, + const STLAllocator<U, V>& b) { + return !(a == b); +} + } // namespace utils
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/linux.h b/libtransport/includes/hicn/transport/utils/linux.h index 5820528e1..105196fd2 100644 --- a/libtransport/includes/hicn/transport/utils/linux.h +++ b/libtransport/includes/hicn/transport/utils/linux.h @@ -17,14 +17,14 @@ #ifdef __linux__ +#include <arpa/inet.h> #include <hicn/transport/portability/portability.h> #include <hicn/transport/utils/log.h> - -#include <arpa/inet.h> #include <ifaddrs.h> #include <netdb.h> #include <stdio.h> #include <sys/socket.h> + #include <string> #define LINK_LOCAL_PREFIX 0xfe80 diff --git a/libtransport/includes/hicn/transport/utils/membuf.h b/libtransport/includes/hicn/transport/utils/membuf.h index 9fc37dd25..0db87e9dd 100644 --- a/libtransport/includes/hicn/transport/utils/membuf.h +++ b/libtransport/includes/hicn/transport/utils/membuf.h @@ -23,6 +23,7 @@ #include <hicn/transport/portability/portability.h> #include <hicn/transport/utils/branch_prediction.h> +#include <stdlib.h> #include <atomic> #include <cassert> @@ -35,8 +36,6 @@ #include <type_traits> #include <vector> -#include <stdlib.h> - #ifndef _WIN32 TRANSPORT_GNU_DISABLE_WARNING("-Wshadow") #endif @@ -50,6 +49,8 @@ class MemBuf { enum TakeOwnershipOp { TAKE_OWNERSHIP }; enum CopyBufferOp { COPY_BUFFER }; + using Ptr = std::shared_ptr<MemBuf>; + typedef void (*FreeFunction)(void* buf, void* userData); static std::unique_ptr<MemBuf> create(std::size_t capacity); @@ -106,13 +107,14 @@ class MemBuf { FreeFunction freeFn = nullptr, void* userData = nullptr, bool freeOnError = true); - static std::unique_ptr<MemBuf> wrapBuffer(const void* buf, + static std::unique_ptr<MemBuf> wrapBuffer(const void* buf, std::size_t length, std::size_t capacity); - static MemBuf wrapBufferAsValue(const void* buf, + static MemBuf wrapBufferAsValue(const void* buf, std::size_t length, std::size_t capacity) noexcept; - MemBuf(WrapBufferOp op, const void* buf, std::size_t capacity) noexcept; + MemBuf(WrapBufferOp op, const void* buf, std::size_t length, + std::size_t capacity) noexcept; /** * Convenience function to create a new MemBuf object that copies data from a @@ -147,6 +149,8 @@ class MemBuf { std::size_t length() const { return length_; } + void setLength(std::size_t length) { length_ = length; } + std::size_t headroom() const { return std::size_t(data_ - buffer()); } std::size_t tailroom() const { return std::size_t(bufferEnd() - tail()); } @@ -689,6 +693,18 @@ class MemBuf { void* userData = nullptr, bool freeOnError = true); + /** + * Ensure the current MemBuf can hold at least capacity bytes and its + * memory is contiguous + */ + bool ensureCapacity(std::size_t capacity); + + /** + * Ensure packet buffer can hold at least 1500 bytes in contiguous memory and + * fill unused memory with placeholder + */ + bool ensureCapacityAndFillUnused(std::size_t capacity, uint8_t placeholder); + /* * Overridden operator new and delete. * These perform specialized memory management to help support @@ -700,6 +716,12 @@ class MemBuf { void operator delete(void* ptr); void operator delete(void* ptr, void* placement); + /** + * Override operator == and != + */ + bool operator ==(const MemBuf &other); + bool operator !=(const MemBuf &other); + // /** // * Iteration support: a chain of MemBufs may be iterated through using // * STL-style iterators over const ByteRanges. Iterators are only diff --git a/libtransport/includes/hicn/transport/utils/move_wrapper.h b/libtransport/includes/hicn/transport/utils/move_wrapper.h new file mode 100644 index 000000000..3aba345d6 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/move_wrapper.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright 2017 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <type_traits> + +namespace utils { + +template <typename F> +struct MoveWrapper : F { + MoveWrapper(F&& f) : F(std::move(f)) {} + + MoveWrapper(MoveWrapper&&) = default; + MoveWrapper& operator=(MoveWrapper&&) = default; + + MoveWrapper(const MoveWrapper&); + MoveWrapper& operator=(const MoveWrapper&); +}; + +template <typename T> +auto moveHandler(T&& t) -> MoveWrapper<typename std::decay<T>::type> { + return std::move(t); +} +} // namespace utils
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/noncopyable.h b/libtransport/includes/hicn/transport/utils/noncopyable.h new file mode 100644 index 000000000..83923e647 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/noncopyable.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace utils { + +class NonCopyable { + protected: + NonCopyable() = default; + ~NonCopyable() = default; + + NonCopyable(const NonCopyable&) = delete; + NonCopyable& operator=(const NonCopyable&) = delete; +}; + +} // namespace utils diff --git a/libtransport/includes/hicn/transport/utils/object_pool.h b/libtransport/includes/hicn/transport/utils/object_pool.h index f78bd2aa2..a5e8b2eef 100644 --- a/libtransport/includes/hicn/transport/utils/object_pool.h +++ b/libtransport/includes/hicn/transport/utils/object_pool.h @@ -17,6 +17,7 @@ // TODO #include <hicn/transport/utils/branch_prediction.h> +#include <hicn/transport/utils/log.h> #include <hicn/transport/utils/spinlock.h> #include <deque> @@ -33,6 +34,7 @@ class ObjectPool { void operator()(T *t) { if (pool_) { + TRANSPORT_LOGV("Back in pool"); pool_->add(t); } else { delete t; @@ -44,10 +46,13 @@ class ObjectPool { }; public: - using Ptr = std::unique_ptr<T, ObjectDeleter>; + using Ptr = std::shared_ptr<T>; ObjectPool() : destructor_(false) {} + // No copies + ObjectPool(const ObjectPool &other) = delete; + ~ObjectPool() { destructor_ = true; for (auto &ptr : object_pool_) { @@ -55,12 +60,17 @@ class ObjectPool { } } + bool empty() { + utils::SpinLock::Acquire locked(object_pool_lock_); + return object_pool_.empty(); + } + std::pair<bool, Ptr> get() { + utils::SpinLock::Acquire locked(object_pool_lock_); if (object_pool_.empty()) { - return std::make_pair<bool, Ptr>(false, makePtr(nullptr)); + return std::make_pair<bool, Ptr>(false, nullptr); } - utils::SpinLock::Acquire locked(object_pool_lock_); auto ret = std::move(object_pool_.front()); object_pool_.pop_front(); return std::make_pair<bool, Ptr>(true, std::move(ret)); @@ -70,7 +80,7 @@ class ObjectPool { utils::SpinLock::Acquire locked(object_pool_lock_); if (TRANSPORT_EXPECT_TRUE(!destructor_)) { - object_pool_.emplace_back(makePtr(object)); + object_pool_.emplace_front(makePtr(object)); } else { delete object; } @@ -79,12 +89,9 @@ class ObjectPool { Ptr makePtr(T *object) { return Ptr(object, ObjectDeleter(this)); } private: - // No copies - ObjectPool(const ObjectPool &other) = delete; - utils::SpinLock object_pool_lock_; std::deque<Ptr> object_pool_; - bool destructor_; + std::atomic<bool> destructor_; }; -} // namespace utils
\ No newline at end of file +} // namespace utils diff --git a/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h new file mode 100644 index 000000000..3387997b5 --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/shared_ptr_utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + */ + +#pragma once + +#include <memory> + +namespace utils { + +template <typename Base> +inline std::shared_ptr<Base> shared_from_base( + std::enable_shared_from_this<Base>* base) { + return base->shared_from_this(); +} + +template <typename Base> +inline std::shared_ptr<const Base> shared_from_base( + std::enable_shared_from_this<Base> const* base) { + return base->shared_from_this(); +} + +template <typename That> +inline std::shared_ptr<That> shared_from(That* that) { + return std::static_pointer_cast<That>(shared_from_base(that)); +} + +} // namespace utils
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/singleton.h b/libtransport/includes/hicn/transport/utils/singleton.h new file mode 100644 index 000000000..7fd8b912f --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/singleton.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <hicn/transport/utils/noncopyable.h> + +namespace utils { + +template <typename T> +class Singleton { + public: + static T& getInstance() { + static T instance; + return instance; + } + + protected: + Singleton() {} + ~Singleton() {} + + public: + Singleton(Singleton const&) = delete; + Singleton& operator=(Singleton const&) = delete; +}; + +} // namespace utils
\ No newline at end of file diff --git a/libtransport/includes/hicn/transport/utils/string_utils.h b/libtransport/includes/hicn/transport/utils/string_utils.h index bfda816f1..313c28cc6 100644 --- a/libtransport/includes/hicn/transport/utils/string_utils.h +++ b/libtransport/includes/hicn/transport/utils/string_utils.h @@ -72,4 +72,4 @@ static inline std::string trim_copy(std::string s) { return s; } -}
\ No newline at end of file +} // namespace utils
\ No newline at end of file |