Drop support from C++17 to C++11
std::optional replaced with Entry in TSLQueue (which is basically a poor man's optional).
This commit is contained in:
parent
7c444cb460
commit
ece17e1aca
4 changed files with 187 additions and 115 deletions
|
@ -21,7 +21,7 @@ add_library(UDPConnection ${UDPConnection_SOURCES})
|
||||||
|
|
||||||
set_target_properties(UDPConnection PROPERTIES VERSION ${UDPConnection_VERSION})
|
set_target_properties(UDPConnection PROPERTIES VERSION ${UDPConnection_VERSION})
|
||||||
|
|
||||||
target_compile_features(UDPConnection PUBLIC cxx_std_17)
|
target_compile_features(UDPConnection PUBLIC cxx_std_11)
|
||||||
target_link_libraries(UDPConnection PUBLIC pthread)
|
target_link_libraries(UDPConnection PUBLIC pthread)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
|
|
149
src/TSLQueue.hpp
149
src/TSLQueue.hpp
|
@ -23,14 +23,40 @@ class TSLQueue {
|
||||||
TSLQueue(TSLQueue &&other);
|
TSLQueue(TSLQueue &&other);
|
||||||
TSLQueue &operator=(TSLQueue &&other);
|
TSLQueue &operator=(TSLQueue &&other);
|
||||||
|
|
||||||
|
// in place of std::optional which is only available in C++17
|
||||||
|
struct Entry {
|
||||||
|
Entry();
|
||||||
|
Entry(const T& value);
|
||||||
|
Entry(T&& rvalue);
|
||||||
|
|
||||||
|
// enable copy
|
||||||
|
Entry(const Entry& other) = default;
|
||||||
|
Entry &operator =(const Entry& other) = default;
|
||||||
|
|
||||||
|
// enable move
|
||||||
|
Entry(Entry&& other) = default;
|
||||||
|
Entry &operator =(Entry&& other) = default;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
NONE,
|
||||||
|
SOME
|
||||||
|
} type;
|
||||||
|
T value;
|
||||||
|
|
||||||
|
bool has_value() const;
|
||||||
|
operator bool () const;
|
||||||
|
T& operator *();
|
||||||
|
const T& operator *() const;
|
||||||
|
};
|
||||||
|
|
||||||
void push(const T &data);
|
void push(const T &data);
|
||||||
bool push_nb(const T &data);
|
bool push_nb(const T &data);
|
||||||
std::optional<T> top();
|
Entry top();
|
||||||
std::optional<T> top_nb();
|
Entry top_nb();
|
||||||
bool pop();
|
bool pop();
|
||||||
std::optional<T> top_and_pop();
|
Entry top_and_pop();
|
||||||
std::optional<T> top_and_pop_and_empty(bool *isEmpty);
|
Entry top_and_pop_and_empty(bool *isEmpty);
|
||||||
std::optional<T> top_and_pop_and_rsize(unsigned long *rsize);
|
Entry top_and_pop_and_rsize(unsigned long *rsize);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
bool empty();
|
bool empty();
|
||||||
|
@ -62,18 +88,18 @@ class TSLQueue {
|
||||||
|
|
||||||
class TSLQIter {
|
class TSLQIter {
|
||||||
public:
|
public:
|
||||||
TSLQIter(std::mutex &mutex,
|
TSLQIter(std::mutex *mutex,
|
||||||
std::weak_ptr<TSLQNode> currentNode,
|
std::weak_ptr<TSLQNode> currentNode,
|
||||||
unsigned long *msize);
|
unsigned long *msize);
|
||||||
~TSLQIter();
|
~TSLQIter();
|
||||||
|
|
||||||
std::optional<T> current();
|
Entry current();
|
||||||
bool next();
|
bool next();
|
||||||
bool prev();
|
bool prev();
|
||||||
bool remove();
|
bool remove();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::lock_guard<std::mutex> lock;
|
std::mutex *mutex;
|
||||||
std::weak_ptr<TSLQNode> currentNode;
|
std::weak_ptr<TSLQNode> currentNode;
|
||||||
unsigned long *const msize;
|
unsigned long *const msize;
|
||||||
|
|
||||||
|
@ -108,7 +134,7 @@ TSLQueue<T>::~TSLQueue() {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TSLQueue<T>::TSLQueue(TSLQueue &&other)
|
TSLQueue<T>::TSLQueue(TSLQueue &&other)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(other.mutex);
|
std::lock_guard<std::mutex> lock(other.mutex);
|
||||||
head = std::move(other.head);
|
head = std::move(other.head);
|
||||||
tail = std::move(other.tail);
|
tail = std::move(other.tail);
|
||||||
msize = std::move(other.msize);
|
msize = std::move(other.msize);
|
||||||
|
@ -116,15 +142,54 @@ TSLQueue<T>::TSLQueue(TSLQueue &&other)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TSLQueue<T> & TSLQueue<T>::operator=(TSLQueue &&other) {
|
TSLQueue<T> & TSLQueue<T>::operator=(TSLQueue &&other) {
|
||||||
std::scoped_lock lock(mutex, other.mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
std::lock_guard<std::mutex> otherLock(other.mutex);
|
||||||
head = std::move(other.head);
|
head = std::move(other.head);
|
||||||
tail = std::move(other.tail);
|
tail = std::move(other.tail);
|
||||||
msize = std::move(other.msize);
|
msize = std::move(other.msize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
TSLQueue<T>::Entry::Entry() :
|
||||||
|
type(Type::NONE),
|
||||||
|
value()
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
TSLQueue<T>::Entry::Entry(const T& value) :
|
||||||
|
type(Type::SOME),
|
||||||
|
value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
TSLQueue<T>::Entry::Entry(T&& value) :
|
||||||
|
type(Type::SOME),
|
||||||
|
value(std::forward<T>(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool TSLQueue<T>::Entry::has_value() const {
|
||||||
|
return type == Type::SOME;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
TSLQueue<T>::Entry::operator bool() const {
|
||||||
|
return has_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& TSLQueue<T>::Entry::operator *() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const T& TSLQueue<T>::Entry::operator *() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TSLQueue<T>::push(const T &data) {
|
void TSLQueue<T>::push(const T &data) {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
auto newNode = std::make_shared<TSLQNode>();
|
auto newNode = std::make_shared<TSLQNode>();
|
||||||
newNode->data = std::make_unique<T>(data);
|
newNode->data = std::make_unique<T>(data);
|
||||||
|
|
||||||
|
@ -161,34 +226,34 @@ bool TSLQueue<T>::push_nb(const T &data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::top() {
|
typename TSLQueue<T>::Entry TSLQueue<T>::top() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if(head->next != tail) {
|
if(head->next != tail) {
|
||||||
assert(head->next->data);
|
assert(head->next->data);
|
||||||
return *head->next->data.get();
|
return Entry(*head->next->data.get());
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return Entry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::top_nb() {
|
typename TSLQueue<T>::Entry TSLQueue<T>::top_nb() {
|
||||||
if(mutex.try_lock()) {
|
if(mutex.try_lock()) {
|
||||||
std::optional<T> ret = std::nullopt;
|
Entry ret;
|
||||||
if(head->next != tail) {
|
if(head->next != tail) {
|
||||||
assert(head->next->data);
|
assert(head->next->data);
|
||||||
ret = *head->next->data.get();
|
ret = Entry(*head->next->data.get());
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return Entry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool TSLQueue<T>::pop() {
|
bool TSLQueue<T>::pop() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if(head->next == tail) {
|
if(head->next == tail) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -203,12 +268,12 @@ bool TSLQueue<T>::pop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::top_and_pop() {
|
typename TSLQueue<T>::Entry TSLQueue<T>::top_and_pop() {
|
||||||
std::optional<T> ret = std::nullopt;
|
Entry ret;
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if(head->next != tail) {
|
if(head->next != tail) {
|
||||||
assert(head->next->data);
|
assert(head->next->data);
|
||||||
ret = *head->next->data.get();
|
ret = Entry(*head->next->data.get());
|
||||||
|
|
||||||
auto& newNext = head->next->next;
|
auto& newNext = head->next->next;
|
||||||
newNext->prev = head;
|
newNext->prev = head;
|
||||||
|
@ -220,16 +285,16 @@ std::optional<T> TSLQueue<T>::top_and_pop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
|
typename TSLQueue<T>::Entry TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
|
||||||
std::optional<T> ret = std::nullopt;
|
Entry ret;
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if(head->next == tail) {
|
if(head->next == tail) {
|
||||||
if(isEmpty) {
|
if(isEmpty) {
|
||||||
*isEmpty = true;
|
*isEmpty = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(head->next->data);
|
assert(head->next->data);
|
||||||
ret = *head->next->data.get();
|
ret = Entry(*head->next->data.get());
|
||||||
|
|
||||||
auto& newNext = head->next->next;
|
auto& newNext = head->next->next;
|
||||||
newNext->prev = head;
|
newNext->prev = head;
|
||||||
|
@ -245,16 +310,16 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::top_and_pop_and_rsize(unsigned long *rsize) {
|
typename TSLQueue<T>::Entry TSLQueue<T>::top_and_pop_and_rsize(unsigned long *rsize) {
|
||||||
std::optional<T> ret = std::nullopt;
|
Entry ret;
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if(head->next == tail) {
|
if(head->next == tail) {
|
||||||
if(rsize) {
|
if(rsize) {
|
||||||
*rsize = 0;
|
*rsize = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(head->next->data);
|
assert(head->next->data);
|
||||||
ret = *head->next->data.get();
|
ret = Entry(*head->next->data.get());
|
||||||
|
|
||||||
auto& newNext = head->next->next;
|
auto& newNext = head->next->next;
|
||||||
newNext->prev = head;
|
newNext->prev = head;
|
||||||
|
@ -271,7 +336,7 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_rsize(unsigned long *rsize) {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TSLQueue<T>::clear() {
|
void TSLQueue<T>::clear() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
head->next = tail;
|
head->next = tail;
|
||||||
tail->prev = head;
|
tail->prev = head;
|
||||||
|
@ -280,13 +345,13 @@ void TSLQueue<T>::clear() {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool TSLQueue<T>::empty() {
|
bool TSLQueue<T>::empty() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
return head->next == tail;
|
return head->next == tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
unsigned long TSLQueue<T>::size() {
|
unsigned long TSLQueue<T>::size() {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
return msize;
|
return msize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,27 +366,29 @@ bool TSLQueue<T>::TSLQNode::isNormal() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TSLQueue<T>::TSLQIter::TSLQIter(std::mutex &mutex,
|
TSLQueue<T>::TSLQIter::TSLQIter(std::mutex *mutex,
|
||||||
std::weak_ptr<TSLQNode> currentNode,
|
std::weak_ptr<TSLQNode> currentNode,
|
||||||
unsigned long *msize) :
|
unsigned long *msize) :
|
||||||
lock(mutex),
|
mutex(mutex),
|
||||||
currentNode(currentNode),
|
currentNode(currentNode),
|
||||||
msize(msize)
|
msize(msize)
|
||||||
{
|
{
|
||||||
|
mutex->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TSLQueue<T>::TSLQIter::~TSLQIter() {
|
TSLQueue<T>::TSLQIter::~TSLQIter() {
|
||||||
|
mutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T> TSLQueue<T>::TSLQIter::current() {
|
typename TSLQueue<T>::Entry TSLQueue<T>::TSLQIter::current() {
|
||||||
std::shared_ptr<TSLQNode> currentNode = this->currentNode.lock();
|
std::shared_ptr<TSLQNode> currentNode = this->currentNode.lock();
|
||||||
assert(currentNode);
|
assert(currentNode);
|
||||||
if(currentNode->isNormal()) {
|
if(currentNode->isNormal()) {
|
||||||
return *currentNode->data.get();
|
return Entry(*currentNode->data.get());
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return Entry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +441,7 @@ bool TSLQueue<T>::TSLQIter::remove() {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename TSLQueue<T>::TSLQIter TSLQueue<T>::begin() {
|
typename TSLQueue<T>::TSLQIter TSLQueue<T>::begin() {
|
||||||
return TSLQIter(mutex, head->next, &msize);
|
return TSLQIter(&mutex, head->next, &msize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -265,7 +265,7 @@ void UDPC::Context::update_impl() {
|
||||||
do {
|
do {
|
||||||
auto optE = internalEvents.top_and_pop();
|
auto optE = internalEvents.top_and_pop();
|
||||||
if(optE.has_value()) {
|
if(optE.has_value()) {
|
||||||
switch(optE.value().type) {
|
switch(optE.value.type) {
|
||||||
case UDPC_ET_REQUEST_CONNECT:
|
case UDPC_ET_REQUEST_CONNECT:
|
||||||
{
|
{
|
||||||
unsigned char *sk = nullptr;
|
unsigned char *sk = nullptr;
|
||||||
|
@ -277,11 +277,11 @@ void UDPC::Context::update_impl() {
|
||||||
UDPC::ConnectionData newCon(
|
UDPC::ConnectionData newCon(
|
||||||
false,
|
false,
|
||||||
this,
|
this,
|
||||||
optE.value().conId.addr,
|
optE.value.conId.addr,
|
||||||
optE.value().conId.scope_id,
|
optE.value.conId.scope_id,
|
||||||
optE.value().conId.port,
|
optE.value.conId.port,
|
||||||
#ifdef UDPC_LIBSODIUM_ENABLED
|
#ifdef UDPC_LIBSODIUM_ENABLED
|
||||||
flags.test(2) && optE.value().v.enableLibSodium != 0,
|
flags.test(2) && optE.value.v.enableLibSodium != 0,
|
||||||
sk, pk);
|
sk, pk);
|
||||||
#else
|
#else
|
||||||
false,
|
false,
|
||||||
|
@ -292,9 +292,9 @@ void UDPC::Context::update_impl() {
|
||||||
UDPC_LoggingType::UDPC_ERROR,
|
UDPC_LoggingType::UDPC_ERROR,
|
||||||
"Failed to init ConnectionData instance (libsodium "
|
"Failed to init ConnectionData instance (libsodium "
|
||||||
"init fail) while client establishing connection with ",
|
"init fail) while client establishing connection with ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port);
|
optE.value.conId.port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
newCon.sent = std::chrono::steady_clock::now() - UDPC::INIT_PKT_INTERVAL_DT;
|
newCon.sent = std::chrono::steady_clock::now() - UDPC::INIT_PKT_INTERVAL_DT;
|
||||||
|
@ -314,34 +314,34 @@ void UDPC::Context::update_impl() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conMap.find(optE.value().conId) == conMap.end()) {
|
if(conMap.find(optE.value.conId) == conMap.end()) {
|
||||||
conMap.insert(std::make_pair(
|
conMap.insert(std::make_pair(
|
||||||
optE.value().conId,
|
optE.value.conId,
|
||||||
std::move(newCon)));
|
std::move(newCon)));
|
||||||
auto addrConIter = addrConMap.find(optE.value().conId.addr);
|
auto addrConIter = addrConMap.find(optE.value.conId.addr);
|
||||||
if(addrConIter == addrConMap.end()) {
|
if(addrConIter == addrConMap.end()) {
|
||||||
auto insertResult = addrConMap.insert(std::make_pair(
|
auto insertResult = addrConMap.insert(std::make_pair(
|
||||||
optE.value().conId.addr,
|
optE.value.conId.addr,
|
||||||
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}));
|
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}));
|
||||||
assert(insertResult.second &&
|
assert(insertResult.second &&
|
||||||
"new connection insert into addrConMap must not fail");
|
"new connection insert into addrConMap must not fail");
|
||||||
addrConIter = insertResult.first;
|
addrConIter = insertResult.first;
|
||||||
}
|
}
|
||||||
addrConIter->second.insert(optE.value().conId);
|
addrConIter->second.insert(optE.value.conId);
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Client initiating connection to ",
|
"Client initiating connection to ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port,
|
optE.value.conId.port,
|
||||||
" ...");
|
" ...");
|
||||||
} else {
|
} else {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_WARNING,
|
UDPC_LoggingType::UDPC_WARNING,
|
||||||
"Client initiate connection, already connected to peer ",
|
"Client initiate connection, already connected to peer ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port);
|
optE.value.conId.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -358,9 +358,9 @@ void UDPC::Context::update_impl() {
|
||||||
UDPC::ConnectionData newCon(
|
UDPC::ConnectionData newCon(
|
||||||
false,
|
false,
|
||||||
this,
|
this,
|
||||||
optE.value().conId.addr,
|
optE.value.conId.addr,
|
||||||
optE.value().conId.scope_id,
|
optE.value.conId.scope_id,
|
||||||
optE.value().conId.port,
|
optE.value.conId.port,
|
||||||
#ifdef UDPC_LIBSODIUM_ENABLED
|
#ifdef UDPC_LIBSODIUM_ENABLED
|
||||||
true,
|
true,
|
||||||
sk, pk);
|
sk, pk);
|
||||||
|
@ -368,18 +368,18 @@ void UDPC::Context::update_impl() {
|
||||||
false,
|
false,
|
||||||
sk, pk);
|
sk, pk);
|
||||||
assert(!"compiled without libsodium support");
|
assert(!"compiled without libsodium support");
|
||||||
delete[] optE.value().v.pk;
|
delete[] optE.value.v.pk;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
if(newCon.flags.test(5)) {
|
if(newCon.flags.test(5)) {
|
||||||
delete[] optE.value().v.pk;
|
delete[] optE.value.v.pk;
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_ERROR,
|
UDPC_LoggingType::UDPC_ERROR,
|
||||||
"Failed to init ConnectionData instance (libsodium "
|
"Failed to init ConnectionData instance (libsodium "
|
||||||
"init fail) while client establishing connection with ",
|
"init fail) while client establishing connection with ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port);
|
optE.value.conId.port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
newCon.sent = std::chrono::steady_clock::now() - UDPC::INIT_PKT_INTERVAL_DT;
|
newCon.sent = std::chrono::steady_clock::now() - UDPC::INIT_PKT_INTERVAL_DT;
|
||||||
|
@ -401,48 +401,48 @@ void UDPC::Context::update_impl() {
|
||||||
// set peer public key
|
// set peer public key
|
||||||
std::memcpy(
|
std::memcpy(
|
||||||
newCon.peer_pk,
|
newCon.peer_pk,
|
||||||
optE.value().v.pk,
|
optE.value.v.pk,
|
||||||
crypto_sign_PUBLICKEYBYTES);
|
crypto_sign_PUBLICKEYBYTES);
|
||||||
newCon.flags.set(7);
|
newCon.flags.set(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] optE.value().v.pk;
|
delete[] optE.value.v.pk;
|
||||||
|
|
||||||
if(conMap.find(optE.value().conId) == conMap.end()) {
|
if(conMap.find(optE.value.conId) == conMap.end()) {
|
||||||
conMap.insert(std::make_pair(
|
conMap.insert(std::make_pair(
|
||||||
optE.value().conId,
|
optE.value.conId,
|
||||||
std::move(newCon)));
|
std::move(newCon)));
|
||||||
auto addrConIter = addrConMap.find(optE.value().conId.addr);
|
auto addrConIter = addrConMap.find(optE.value.conId.addr);
|
||||||
if(addrConIter == addrConMap.end()) {
|
if(addrConIter == addrConMap.end()) {
|
||||||
auto insertResult = addrConMap.insert(std::make_pair(
|
auto insertResult = addrConMap.insert(std::make_pair(
|
||||||
optE.value().conId.addr,
|
optE.value.conId.addr,
|
||||||
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}));
|
std::unordered_set<UDPC_ConnectionId, UDPC::ConnectionIdHasher>{}));
|
||||||
assert(insertResult.second &&
|
assert(insertResult.second &&
|
||||||
"new connection insert into addrConMap must not fail");
|
"new connection insert into addrConMap must not fail");
|
||||||
addrConIter = insertResult.first;
|
addrConIter = insertResult.first;
|
||||||
}
|
}
|
||||||
addrConIter->second.insert(optE.value().conId);
|
addrConIter->second.insert(optE.value.conId);
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_INFO,
|
UDPC_LoggingType::UDPC_INFO,
|
||||||
"Client initiating connection to ",
|
"Client initiating connection to ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port,
|
optE.value.conId.port,
|
||||||
" ...");
|
" ...");
|
||||||
} else {
|
} else {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_WARNING,
|
UDPC_LoggingType::UDPC_WARNING,
|
||||||
"Client initiate connection, already connected to peer ",
|
"Client initiate connection, already connected to peer ",
|
||||||
UDPC_atostr((UDPC_HContext)this, optE.value().conId.addr),
|
UDPC_atostr((UDPC_HContext)this, optE.value.conId.addr),
|
||||||
" port ",
|
" port ",
|
||||||
optE.value().conId.port);
|
optE.value.conId.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UDPC_ET_REQUEST_DISCONNECT:
|
case UDPC_ET_REQUEST_DISCONNECT:
|
||||||
if(optE.value().v.dropAllWithAddr != 0) {
|
if(optE.value.v.dropAllWithAddr != 0) {
|
||||||
// drop all connections with same address
|
// drop all connections with same address
|
||||||
auto addrConIter = addrConMap.find(optE.value().conId.addr);
|
auto addrConIter = addrConMap.find(optE.value.conId.addr);
|
||||||
if(addrConIter != addrConMap.end()) {
|
if(addrConIter != addrConMap.end()) {
|
||||||
for(auto identIter = addrConIter->second.begin();
|
for(auto identIter = addrConIter->second.begin();
|
||||||
identIter != addrConIter->second.end();
|
identIter != addrConIter->second.end();
|
||||||
|
@ -463,14 +463,14 @@ void UDPC::Context::update_impl() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// drop only specific connection with addr and port
|
// drop only specific connection with addr and port
|
||||||
auto iter = conMap.find(optE.value().conId);
|
auto iter = conMap.find(optE.value.conId);
|
||||||
if(iter != conMap.end()) {
|
if(iter != conMap.end()) {
|
||||||
if(iter->second.flags.test(4)) {
|
if(iter->second.flags.test(4)) {
|
||||||
idMap.erase(iter->second.id);
|
idMap.erase(iter->second.id);
|
||||||
}
|
}
|
||||||
auto addrConIter = addrConMap.find(optE.value().conId.addr);
|
auto addrConIter = addrConMap.find(optE.value.conId.addr);
|
||||||
if(addrConIter != addrConMap.end()) {
|
if(addrConIter != addrConMap.end()) {
|
||||||
addrConIter->second.erase(optE.value().conId);
|
addrConIter->second.erase(optE.value.conId);
|
||||||
if(addrConIter->second.empty()) {
|
if(addrConIter->second.empty()) {
|
||||||
addrConMap.erase(addrConIter);
|
addrConMap.erase(addrConIter);
|
||||||
}
|
}
|
||||||
|
@ -607,18 +607,18 @@ void UDPC::Context::update_impl() {
|
||||||
while(true) {
|
while(true) {
|
||||||
auto next = sendIter.current();
|
auto next = sendIter.current();
|
||||||
if(next) {
|
if(next) {
|
||||||
if(auto iter = conMap.find(next.value().receiver);
|
auto iter = conMap.find(next.value.receiver);
|
||||||
iter != conMap.end()) {
|
if(iter != conMap.end()) {
|
||||||
if(iter->second.sendPkts.size() >= UDPC_QUEUED_PKTS_MAX_SIZE) {
|
if(iter->second.sendPkts.size() >= UDPC_QUEUED_PKTS_MAX_SIZE) {
|
||||||
if(notQueued.find(next.value().receiver) == notQueued.end()) {
|
if(notQueued.find(next.value.receiver) == notQueued.end()) {
|
||||||
notQueued.insert(next.value().receiver);
|
notQueued.insert(next.value.receiver);
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_DEBUG,
|
UDPC_LoggingType::UDPC_DEBUG,
|
||||||
"Not queueing packet to ",
|
"Not queueing packet to ",
|
||||||
UDPC_atostr((UDPC_HContext)this,
|
UDPC_atostr((UDPC_HContext)this,
|
||||||
next.value().receiver.addr),
|
next.value.receiver.addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
next.value().receiver.port,
|
next.value.receiver.port,
|
||||||
", connection's queue reached max size");
|
", connection's queue reached max size");
|
||||||
}
|
}
|
||||||
if(sendIter.next()) {
|
if(sendIter.next()) {
|
||||||
|
@ -627,24 +627,24 @@ void UDPC::Context::update_impl() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iter->second.sendPkts.push_back(next.value());
|
iter->second.sendPkts.push_back(next.value);
|
||||||
if(sendIter.remove()) {
|
if(sendIter.remove()) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(dropped.find(next.value().receiver) == dropped.end()) {
|
if(dropped.find(next.value.receiver) == dropped.end()) {
|
||||||
UDPC_CHECK_LOG(this,
|
UDPC_CHECK_LOG(this,
|
||||||
UDPC_LoggingType::UDPC_WARNING,
|
UDPC_LoggingType::UDPC_WARNING,
|
||||||
"Dropped queued packets to ",
|
"Dropped queued packets to ",
|
||||||
UDPC_atostr(
|
UDPC_atostr(
|
||||||
(UDPC_HContext)this,
|
(UDPC_HContext)this,
|
||||||
next.value().receiver.addr),
|
next.value.receiver.addr),
|
||||||
", port = ",
|
", port = ",
|
||||||
next.value().receiver.port,
|
next.value.receiver.port,
|
||||||
" due to connection not existing");
|
" due to connection not existing");
|
||||||
dropped.insert(next.value().receiver);
|
dropped.insert(next.value.receiver);
|
||||||
}
|
}
|
||||||
if(sendIter.remove()) {
|
if(sendIter.remove()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1589,17 +1589,22 @@ UDPC::Context *UDPC::verifyContext(UDPC_HContext ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDPC::isBigEndian() {
|
bool UDPC::isBigEndian() {
|
||||||
static std::optional<bool> isBigEndian = std::nullopt;
|
/*
|
||||||
if(isBigEndian) {
|
* 0 - unset
|
||||||
return *isBigEndian;
|
* 1 - is big endian
|
||||||
|
* 2 - is not big endian
|
||||||
|
*/
|
||||||
|
static char isBigEndian = 0;
|
||||||
|
if(isBigEndian != 0) {
|
||||||
|
return isBigEndian == 1;
|
||||||
}
|
}
|
||||||
union {
|
union {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
char c[4];
|
char c[4];
|
||||||
} bint = {0x01020304};
|
} bint = {0x01020304};
|
||||||
|
|
||||||
isBigEndian = (bint.c[0] == 1);
|
isBigEndian = (bint.c[0] == 1 ? 1 : 2);
|
||||||
return *isBigEndian;
|
return isBigEndian;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPC::preparePacket(
|
void UDPC::preparePacket(
|
||||||
|
@ -1923,8 +1928,8 @@ void UDPC_destroy(UDPC_HContext ctx) {
|
||||||
#endif
|
#endif
|
||||||
while(!UDPC_ctx->internalEvents.empty()) {
|
while(!UDPC_ctx->internalEvents.empty()) {
|
||||||
auto optE = UDPC_ctx->internalEvents.top_and_pop();
|
auto optE = UDPC_ctx->internalEvents.top_and_pop();
|
||||||
if(optE.has_value() && optE.value().type == UDPC_ET_REQUEST_CONNECT_PK) {
|
if(optE.has_value() && optE.value.type == UDPC_ET_REQUEST_CONNECT_PK) {
|
||||||
delete[] optE.value().v.pk;
|
delete[] optE.value.v.pk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UDPC_ctx->_contextIdentifier = 0;
|
UDPC_ctx->_contextIdentifier = 0;
|
||||||
|
@ -2141,7 +2146,7 @@ UDPC_Event UDPC_get_event(UDPC_HContext ctx, unsigned long *remaining) {
|
||||||
|
|
||||||
auto optE = c->externalEvents.top_and_pop_and_rsize(remaining);
|
auto optE = c->externalEvents.top_and_pop_and_rsize(remaining);
|
||||||
if(optE) {
|
if(optE) {
|
||||||
return optE.value();
|
return optE.value;
|
||||||
} else {
|
} else {
|
||||||
return UDPC_Event{UDPC_ET_NONE, UDPC_create_id_anyaddr(0), 0};
|
return UDPC_Event{UDPC_ET_NONE, UDPC_create_id_anyaddr(0), 0};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ TEST(TSLQueue, PushTopPopSize) {
|
||||||
for(int i = 0; i < 10; ++i) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
auto v = q.top();
|
auto v = q.top();
|
||||||
ASSERT_TRUE(v.has_value());
|
ASSERT_TRUE(v.has_value());
|
||||||
EXPECT_EQ(v.value(), i);
|
EXPECT_EQ(v.value, i);
|
||||||
EXPECT_EQ(10 - i, q.size());
|
EXPECT_EQ(10 - i, q.size());
|
||||||
EXPECT_TRUE(q.pop());
|
EXPECT_TRUE(q.pop());
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,11 @@ TEST(TSLQueue, PushNB_TopNB_TopAndPop_Size) {
|
||||||
for(int i = 0; i < 10; ++i) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
auto v = q.top_nb();
|
auto v = q.top_nb();
|
||||||
ASSERT_TRUE(v.has_value());
|
ASSERT_TRUE(v.has_value());
|
||||||
EXPECT_EQ(v.value(), i);
|
EXPECT_EQ(v.value, i);
|
||||||
EXPECT_EQ(q.size(), 10 - i);
|
EXPECT_EQ(q.size(), 10 - i);
|
||||||
v = q.top_and_pop();
|
v = q.top_and_pop();
|
||||||
ASSERT_TRUE(v.has_value());
|
ASSERT_TRUE(v.has_value());
|
||||||
EXPECT_EQ(v.value(), i);
|
EXPECT_EQ(v.value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ TEST(TSLQueue, Push_TopAndPopAndEmpty_Size) {
|
||||||
EXPECT_EQ(q.size(), 10 - i);
|
EXPECT_EQ(q.size(), 10 - i);
|
||||||
auto v = q.top_and_pop_and_empty(&isEmpty);
|
auto v = q.top_and_pop_and_empty(&isEmpty);
|
||||||
ASSERT_TRUE(v.has_value());
|
ASSERT_TRUE(v.has_value());
|
||||||
EXPECT_EQ(v.value(), i);
|
EXPECT_EQ(v.value, i);
|
||||||
EXPECT_EQ(i == 9, isEmpty);
|
EXPECT_EQ(i == 9, isEmpty);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(q.size(), 0);
|
EXPECT_EQ(q.size(), 0);
|
||||||
|
@ -110,8 +110,8 @@ TEST(TSLQueue, Concurrent) {
|
||||||
EXPECT_EQ(q.size(), 100 - i);
|
EXPECT_EQ(q.size(), 100 - i);
|
||||||
auto v = q.top_and_pop();
|
auto v = q.top_and_pop();
|
||||||
ASSERT_TRUE(v.has_value());
|
ASSERT_TRUE(v.has_value());
|
||||||
EXPECT_GE(v.value(), 0);
|
EXPECT_GE(v.value, 0);
|
||||||
EXPECT_LE(v.value(), 100);
|
EXPECT_LE(v.value, 100);
|
||||||
EXPECT_EQ(i == 99, q.empty());
|
EXPECT_EQ(i == 99, q.empty());
|
||||||
}
|
}
|
||||||
EXPECT_EQ(q.size(), 0);
|
EXPECT_EQ(q.size(), 0);
|
||||||
|
@ -131,7 +131,7 @@ TEST(TSLQueue, Iterator) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
auto op = iter.current();
|
auto op = iter.current();
|
||||||
while(op.has_value()) {
|
while(op.has_value()) {
|
||||||
EXPECT_EQ(op.value(), i++);
|
EXPECT_EQ(op.value, i++);
|
||||||
if(i < 10) {
|
if(i < 10) {
|
||||||
EXPECT_TRUE(iter.next());
|
EXPECT_TRUE(iter.next());
|
||||||
} else {
|
} else {
|
||||||
|
@ -149,7 +149,7 @@ TEST(TSLQueue, Iterator) {
|
||||||
EXPECT_TRUE(iter.prev());
|
EXPECT_TRUE(iter.prev());
|
||||||
op = iter.current();
|
op = iter.current();
|
||||||
while(op.has_value()) {
|
while(op.has_value()) {
|
||||||
EXPECT_EQ(op.value(), --i);
|
EXPECT_EQ(op.value, --i);
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
EXPECT_TRUE(iter.prev());
|
EXPECT_TRUE(iter.prev());
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,22 +169,22 @@ TEST(TSLQueue, Iterator) {
|
||||||
|
|
||||||
auto op = iter.current();
|
auto op = iter.current();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
EXPECT_EQ(op.value(), 4);
|
EXPECT_EQ(op.value, 4);
|
||||||
|
|
||||||
EXPECT_TRUE(iter.prev());
|
EXPECT_TRUE(iter.prev());
|
||||||
op = iter.current();
|
op = iter.current();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
EXPECT_EQ(op.value(), 2);
|
EXPECT_EQ(op.value, 2);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(q.size(), 9);
|
EXPECT_EQ(q.size(), 9);
|
||||||
|
|
||||||
// check that "3" was removed from queue
|
// check that "3" was removed from queue
|
||||||
int i = 0;
|
int i = 0;
|
||||||
std::optional<int> op;
|
TSLQueue<int>::Entry op;
|
||||||
while(!q.empty()) {
|
while(!q.empty()) {
|
||||||
op = q.top();
|
op = q.top();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
EXPECT_EQ(i++, op.value());
|
EXPECT_EQ(i++, op.value);
|
||||||
if(i == 3) {
|
if(i == 3) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ TEST(TSLQueue, Iterator) {
|
||||||
while(!q.empty()) {
|
while(!q.empty()) {
|
||||||
op = q.top();
|
op = q.top();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
EXPECT_EQ(i++, op.value());
|
EXPECT_EQ(i++, op.value);
|
||||||
EXPECT_TRUE(q.pop());
|
EXPECT_TRUE(q.pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ TEST(TSLQueue, Iterator) {
|
||||||
EXPECT_TRUE(iter.next());
|
EXPECT_TRUE(iter.next());
|
||||||
op = iter.current();
|
op = iter.current();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
if(op.value() == 3) {
|
if(op.value == 3) {
|
||||||
EXPECT_FALSE(iter.remove());
|
EXPECT_FALSE(iter.remove());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ TEST(TSLQueue, Iterator) {
|
||||||
while(!q.empty()) {
|
while(!q.empty()) {
|
||||||
op = q.top();
|
op = q.top();
|
||||||
EXPECT_TRUE(op.has_value());
|
EXPECT_TRUE(op.has_value());
|
||||||
EXPECT_EQ(i++, op.value());
|
EXPECT_EQ(i++, op.value);
|
||||||
EXPECT_TRUE(q.pop());
|
EXPECT_TRUE(q.pop());
|
||||||
if(i == 3) {
|
if(i == 3) {
|
||||||
EXPECT_TRUE(q.empty());
|
EXPECT_TRUE(q.empty());
|
||||||
|
|
Loading…
Reference in a new issue