Skip to content

Commit

Permalink
Stability & wallet sync enhancements (#223)
Browse files Browse the repository at this point in the history
-    Wallet synchronization enhancements
-    Daemon stability enhancements
-    Correct application closing
  • Loading branch information
aivve authored May 4, 2024
1 parent 6fd2345 commit 85c1eaa
Show file tree
Hide file tree
Showing 37 changed files with 489 additions and 227 deletions.
40 changes: 24 additions & 16 deletions src/Platform/Linux/System/Dispatcher.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand All @@ -17,6 +18,7 @@

#include "Dispatcher.h"
#include <cassert>

#include <fcntl.h>
#include <pthread.h>
#include <sys/epoll.h>
Expand Down Expand Up @@ -56,8 +58,7 @@ class MutextGuard {

static_assert(Dispatcher::SIZEOF_PTHREAD_MUTEX_T == sizeof(pthread_mutex_t), "invalid pthread mutex size");

//const size_t STACK_SIZE = 64 * 1024;
const size_t STACK_SIZE = 512 * 1024;
const size_t STACK_SIZE = 64 * 1024;

};

Expand Down Expand Up @@ -104,11 +105,13 @@ Dispatcher::Dispatcher() {
}

auto result = close(remoteSpawnEvent);
if (result) {}
assert(result == 0);
}
}

auto result = close(epoll);
if (result) {}
assert(result == 0);
}

Expand All @@ -135,11 +138,13 @@ Dispatcher::~Dispatcher() {

while (!timers.empty()) {
int result = ::close(timers.top());
if (result) {}
assert(result == 0);
timers.pop();
}

auto result = close(epoll);
if (result) {}
assert(result == 0);
result = close(remoteSpawnEvent);
assert(result == 0);
Expand Down Expand Up @@ -172,8 +177,10 @@ void Dispatcher::dispatch() {
if (firstResumingContext != nullptr) {
context = firstResumingContext;
firstResumingContext = context->next;
//assert(context->inExecutionQueue);

assert(context->inExecutionQueue);
context->inExecutionQueue = false;

break;
}

Expand Down Expand Up @@ -256,10 +263,13 @@ bool Dispatcher::interrupted() {

void Dispatcher::pushContext(NativeContext* context) {
assert(context != nullptr);

if (context->inExecutionQueue)
return;

context->next = nullptr;
context->inExecutionQueue = true;

if(firstResumingContext != nullptr) {
assert(lastResumingContext != nullptr);
lastResumingContext->next = context;
Expand Down Expand Up @@ -330,23 +340,21 @@ void Dispatcher::yield() {
}

if ((events[i].events & EPOLLOUT) != 0) {
if(contextPair->writeContext != nullptr) {
if(contextPair->writeContext->context != nullptr) {
if (contextPair->writeContext != nullptr) {
if (contextPair->writeContext->context != nullptr) {
contextPair->writeContext->context->interruptProcedure = nullptr;
}
pushContext(contextPair->writeContext->context);
contextPair->writeContext->events = events[i].events;
}
pushContext(contextPair->writeContext->context);
contextPair->writeContext->events = events[i].events;
} else if ((events[i].events & EPOLLIN) != 0) {
if(contextPair->readContext != nullptr) {
if(contextPair->readContext->context != nullptr) {
if (contextPair->readContext != nullptr) {
if (contextPair->readContext->context != nullptr) {
contextPair->readContext->context->interruptProcedure = nullptr;
}
pushContext(contextPair->readContext->context);
contextPair->readContext->events = events[i].events;
}
pushContext(contextPair->readContext->context);
contextPair->readContext->events = events[i].events;
} else if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0) {
throw std::runtime_error("Dispatcher::dispatch, events & (EPOLLERR | EPOLLHUP) != 0");
} else {
continue;
}
Expand Down Expand Up @@ -408,7 +416,7 @@ int Dispatcher::getTimer() {
if (timers.empty()) {
timer = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
epoll_event timerEvent;
timerEvent.events = 0;
timerEvent.events = EPOLLONESHOT;
timerEvent.data.ptr = nullptr;

if (epoll_ctl(getEpoll(), EPOLL_CTL_ADD, timer, &timerEvent) == -1) {
Expand Down Expand Up @@ -443,7 +451,7 @@ void Dispatcher::contextProcedure(void* ucontext) {
++runningContextCount;
try {
context.procedure();
} catch(std::exception&) {
} catch(...) {
}

if (context.group != nullptr) {
Expand Down
5 changes: 4 additions & 1 deletion src/Platform/Linux/System/Dispatcher.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand All @@ -19,9 +20,11 @@

#include <cstddef>
#include <cstdint>
#include <exception>
#include <functional>
#include <queue>
#include <stack>
#include <stdexcept>
#ifndef __GLIBC__
#include <bits/reg.h>
#endif
Expand Down
22 changes: 15 additions & 7 deletions src/Platform/Linux/System/TcpConnection.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down Expand Up @@ -48,6 +49,7 @@ TcpConnection::~TcpConnection() {
assert(contextPair.readContext == nullptr);
assert(contextPair.writeContext == nullptr);
int result = close(connection);
if (result) {}
assert(result != -1);
}
}
Expand Down Expand Up @@ -83,7 +85,10 @@ size_t TcpConnection::read(uint8_t* data, size_t size) {
std::string message;
ssize_t transferred = ::recv(connection, (void *)data, size, 0);
if (transferred == -1) {
if (errno != EAGAIN) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
if (errno != EAGAIN && errno != EWOULDBLOCK) {
#pragma GCC diagnostic pop
message = "recv failed, " + lastErrorMessage();
} else {
epoll_event connectionEvent;
Expand All @@ -106,11 +111,11 @@ size_t TcpConnection::read(uint8_t* data, size_t size) {
assert(dispatcher != nullptr);
assert(contextPair.readContext != nullptr);
epoll_event connectionEvent;
connectionEvent.events = 0;
connectionEvent.events = EPOLLONESHOT;
connectionEvent.data.ptr = nullptr;

if (epoll_ctl(dispatcher->getEpoll(), EPOLL_CTL_MOD, connection, &connectionEvent) == -1) {
throw std::runtime_error("TcpConnection::stop, epoll_ctl failed, " + lastErrorMessage());
throw std::runtime_error("TcpConnection::read, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
}

contextPair.readContext->interrupted = true;
Expand Down Expand Up @@ -179,7 +184,10 @@ std::size_t TcpConnection::write(const uint8_t* data, size_t size) {

ssize_t transferred = ::send(connection, (void *)data, size, MSG_NOSIGNAL);
if (transferred == -1) {
if (errno != EAGAIN) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
if (errno != EAGAIN && errno != EWOULDBLOCK) {
#pragma GCC diagnostic pop
message = "send failed, " + lastErrorMessage();
} else {
epoll_event connectionEvent;
Expand All @@ -202,11 +210,11 @@ std::size_t TcpConnection::write(const uint8_t* data, size_t size) {
assert(dispatcher != nullptr);
assert(contextPair.writeContext != nullptr);
epoll_event connectionEvent;
connectionEvent.events = 0;
connectionEvent.events = EPOLLONESHOT;
connectionEvent.data.ptr = nullptr;

if (epoll_ctl(dispatcher->getEpoll(), EPOLL_CTL_MOD, connection, &connectionEvent) == -1) {
throw std::runtime_error("TcpConnection::stop, epoll_ctl failed, " + lastErrorMessage());
throw std::runtime_error("TcpConnection::write, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
}

contextPair.writeContext->interrupted = true;
Expand Down
3 changes: 2 additions & 1 deletion src/Platform/Linux/System/TcpConnection.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down
5 changes: 4 additions & 1 deletion src/Platform/Linux/System/TcpConnector.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down Expand Up @@ -144,6 +145,7 @@ TcpConnection TcpConnector::connect(const Ipv4Address& address, uint16_t port) {
} else {
if((connectorContext.events & (EPOLLERR | EPOLLHUP)) != 0) {
int result = close(connection);
if (result) {}
assert(result != -1);

throw std::runtime_error("TcpConnector::connect, connection failed");
Expand Down Expand Up @@ -171,6 +173,7 @@ TcpConnection TcpConnector::connect(const Ipv4Address& address, uint16_t port) {
}

int result = close(connection);
if (result) {}
assert(result != -1);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Platform/Linux/System/TcpConnector.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down
12 changes: 8 additions & 4 deletions src/Platform/Linux/System/TcpListener.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down Expand Up @@ -60,7 +61,7 @@ TcpListener::TcpListener(Dispatcher& dispatcher, const Ipv4Address& addr, uint16
message = "listen failed, " + lastErrorMessage();
} else {
epoll_event listenEvent;
listenEvent.events = 0;
listenEvent.events = EPOLLONESHOT;
listenEvent.data.ptr = nullptr;

if (epoll_ctl(dispatcher.getEpoll(), EPOLL_CTL_ADD, listener, &listenEvent) == -1) {
Expand All @@ -74,6 +75,7 @@ TcpListener::TcpListener(Dispatcher& dispatcher, const Ipv4Address& addr, uint16
}

int result = close(listener);
if (result) {}
assert(result != -1);
}

Expand All @@ -93,6 +95,7 @@ TcpListener::~TcpListener() {
if (dispatcher != nullptr) {
assert(context == nullptr);
int result = close(listener);
if (result) {}
assert(result != -1);
}
}
Expand Down Expand Up @@ -145,11 +148,11 @@ TcpConnection TcpListener::accept() {
OperationContext* listenerContext = static_cast<OperationContext*>(context);
if (!listenerContext->interrupted) {
epoll_event listenEvent;
listenEvent.events = 0;
listenEvent.events = EPOLLONESHOT;
listenEvent.data.ptr = nullptr;

if (epoll_ctl(dispatcher->getEpoll(), EPOLL_CTL_MOD, listener, &listenEvent) == -1) {
throw std::runtime_error("TcpListener::stop, epoll_ctl failed, " + lastErrorMessage() );
throw std::runtime_error("TcpListener::accept, interrupt procedure, epoll_ctl failed, " + lastErrorMessage() );
}

listenerContext->interrupted = true;
Expand Down Expand Up @@ -187,6 +190,7 @@ TcpConnection TcpListener::accept() {
}

int result = close(connection);
if (result) {}
assert(result != -1);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/Platform/Linux/System/TcpListener.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down
12 changes: 8 additions & 4 deletions src/Platform/Linux/System/Timer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down Expand Up @@ -102,23 +103,26 @@ void Timer::sleep(std::chrono::nanoseconds duration) {
if (!timerContext->interrupted) {
uint64_t value = 0;
if(::read(timer, &value, sizeof value) == -1 ){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
if(errno == EAGAIN || errno == EWOULDBLOCK) {
#pragma GCC diagnostic pop
timerContext->interrupted = true;
dispatcher->pushContext(timerContext->context);
} else {
throw std::runtime_error("Timer::interrupt, read failed, " + lastErrorMessage());
throw std::runtime_error("Timer::sleep, interrupt procedure, read failed, " + lastErrorMessage());
}
} else {
assert(value>0);
dispatcher->pushContext(timerContext->context);
}

epoll_event timerEvent;
timerEvent.events = 0;
timerEvent.events = EPOLLONESHOT;
timerEvent.data.ptr = nullptr;

if (epoll_ctl(dispatcher->getEpoll(), EPOLL_CTL_MOD, timer, &timerEvent) == -1) {
throw std::runtime_error("Timer::interrupt, epoll_ctl failed, " + lastErrorMessage());
throw std::runtime_error("Timer::sleep, interrupt procedure, epoll_ctl failed, " + lastErrorMessage());
}
}
};
Expand Down
3 changes: 2 additions & 1 deletion src/Platform/Linux/System/Timer.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2016, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2016-2019, The Karbo developers
//
// This file is part of Karbo.
//
Expand Down
Loading

0 comments on commit 85c1eaa

Please sign in to comment.