atomics have been used for threads stop

This commit is contained in:
brain5lug 2017-10-01 00:46:49 +03:00
parent 8c09a7429c
commit dfa1482ab2
15 changed files with 259 additions and 212 deletions

View file

@ -15,7 +15,7 @@ namespace util
virtual bool init(int argc, char* argv[]);
virtual bool start();
virtual bool stop();
virtual void run () {};
virtual void run () {}
bool isDaemon;
bool running;

View file

@ -943,44 +943,50 @@ namespace http {
void HTTPServer::Start ()
{
bool needAuth; i2p::config::GetOption("http.auth", needAuth);
std::string user; i2p::config::GetOption("http.user", user);
std::string pass; i2p::config::GetOption("http.pass", pass);
/* generate pass if needed */
if (needAuth && pass == "") {
uint8_t random[16];
char alnum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
pass.resize(sizeof(random));
RAND_bytes(random, sizeof(random));
for (size_t i = 0; i < sizeof(random); i++) {
pass[i] = alnum[random[i] % (sizeof(alnum) - 1)];
if (!m_IsRunning.load())
{
bool needAuth; i2p::config::GetOption("http.auth", needAuth);
std::string user; i2p::config::GetOption("http.user", user);
std::string pass; i2p::config::GetOption("http.pass", pass);
/* generate pass if needed */
if (needAuth && pass == "") {
uint8_t random[16];
char alnum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
pass.resize(sizeof(random));
RAND_bytes(random, sizeof(random));
for (size_t i = 0; i < sizeof(random); i++) {
pass[i] = alnum[random[i] % (sizeof(alnum) - 1)];
}
i2p::config::SetOption("http.pass", pass);
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
}
i2p::config::SetOption("http.pass", pass);
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
m_IsRunning.store(true);
m_Thread = std::unique_ptr<std::thread>(new std::thread (std::bind (&HTTPServer::Run, this)));
m_Acceptor.listen ();
Accept ();
}
m_IsRunning = true;
m_Thread = std::unique_ptr<std::thread>(new std::thread (std::bind (&HTTPServer::Run, this)));
m_Acceptor.listen ();
Accept ();
}
void HTTPServer::Stop ()
{
m_IsRunning = false;
m_Acceptor.close();
m_Service.stop ();
if (m_Thread)
if (m_IsRunning.load())
{
m_Thread->join ();
m_Thread = nullptr;
m_IsRunning.store(false);
m_Acceptor.close();
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
m_Thread = nullptr;
}
}
}
void HTTPServer::Run ()
{
while (m_IsRunning)
while (m_IsRunning.load(std::memory_order_acquire))
{
try
{

View file

@ -8,6 +8,7 @@
#include <thread>
#include <boost/asio.hpp>
#include <sstream>
#include <atomic>
#include "HTTP.h"
namespace i2p
@ -70,7 +71,7 @@ namespace http
private:
bool m_IsRunning;
std::atomic_bool m_IsRunning;
std::unique_ptr<std::thread> m_Thread;
boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work;

View file

@ -101,19 +101,19 @@ namespace client
void I2PControlService::Start ()
{
if (!m_IsRunning)
if (!m_IsRunning.load())
{
Accept ();
m_IsRunning = true;
m_IsRunning.store(true);
m_Thread = new std::thread (std::bind (&I2PControlService::Run, this));
}
}
void I2PControlService::Stop ()
{
if (m_IsRunning)
if (m_IsRunning.load())
{
m_IsRunning = false;
m_IsRunning.store(false);
m_Acceptor.cancel ();
m_Service.stop ();
if (m_Thread)
@ -127,7 +127,7 @@ namespace client
void I2PControlService::Run ()
{
while (m_IsRunning)
while (m_IsRunning.load(std::memory_order_acquire))
{
try {
m_Service.run ();
@ -160,7 +160,7 @@ namespace client
void I2PControlService::Handshake (std::shared_ptr<ssl_socket> socket)
{
socket->async_handshake(boost::asio::ssl::stream_base::server,
std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket));
std::bind( &I2PControlService::HandleHandshake, this, std::placeholders::_1, socket));
}
void I2PControlService::HandleHandshake (const boost::system::error_code& ecode, std::shared_ptr<ssl_socket> socket)

View file

@ -9,6 +9,7 @@
#include <sstream>
#include <map>
#include <set>
#include <atomic>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/property_tree/ptree.hpp>
@ -101,7 +102,7 @@ namespace client
private:
std::string m_Password;
bool m_IsRunning;
std::atomic_bool m_IsRunning;
std::thread * m_Thread;
boost::asio::io_service m_Service;

View file

@ -28,10 +28,10 @@ namespace transport
void UPnP::Stop ()
{
if (m_IsRunning)
if (m_IsRunning.load())
{
LogPrint(eLogInfo, "UPnP: stopping");
m_IsRunning = false;
m_IsRunning.store(false);
m_Timer.cancel ();
m_Service.stop ();
if (m_Thread)
@ -46,12 +46,15 @@ namespace transport
void UPnP::Start()
{
m_IsRunning = true;
LogPrint(eLogInfo, "UPnP: starting");
m_Service.post (std::bind (&UPnP::Discover, this));
std::unique_lock<std::mutex> l(m_StartedMutex);
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum
if (!m_IsRunning.load())
{
m_IsRunning.store(true);
LogPrint(eLogInfo, "UPnP: starting");
m_Service.post (std::bind (&UPnP::Discover, this));
std::unique_lock<std::mutex> l(m_StartedMutex);
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum
}
}
UPnP::~UPnP ()
@ -61,7 +64,7 @@ namespace transport
void UPnP::Run ()
{
while (m_IsRunning)
while (m_IsRunning.load(std::memory_order_acquire))
{
try
{

View file

@ -7,6 +7,7 @@
#include <condition_variable>
#include <mutex>
#include <memory>
#include <atomic>
#include <miniupnpc/miniwget.h>
#include <miniupnpc/miniupnpc.h>
@ -43,8 +44,8 @@ namespace transport
private:
bool m_IsRunning;
std::unique_ptr<std::thread> m_Thread;
std::atomic_bool m_IsRunning;
std::unique_ptr<std::thread> m_Thread;
std::condition_variable m_Started;
std::mutex m_StartedMutex;
boost::asio::io_service m_Service;