mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-29 00:27:27 -04:00
Solve race condition in JSON API restart
Improve atomic access to restbed service Protect JSON API restart against bursts Fix JSON API error condition enum registration Provide ostream helper for error_condition Provide optional forced thread cancel for debugging purpose, disabled by default at compile time define RS_THREAD_FORCE_STOP to enable it Avoid double fullstop in retroshare-gui json api apply button
This commit is contained in:
parent
7757c685c5
commit
039e8f653d
8 changed files with 236 additions and 72 deletions
|
@ -3,7 +3,9 @@
|
|||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -21,11 +23,25 @@
|
|||
*******************************************************************************/
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "util/rsdir.h"
|
||||
|
||||
std::ostream &operator<<(std::ostream& out, const std::error_condition& err)
|
||||
{
|
||||
return out << " error: " << err.value() << " " << err.message()
|
||||
<< " category: " << err.category().name();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// All the following lines are DEPRECATED!!
|
||||
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/rstime.h"
|
||||
|
||||
const int RS_DEBUG_STDERR = 1; /* stuff goes to stderr */
|
||||
|
@ -186,6 +202,3 @@ void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg
|
|||
lineCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* RetroShare debugging utilities *
|
||||
* *
|
||||
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2019-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -21,6 +22,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <system_error>
|
||||
|
||||
/** Stream helper for std::error_condition */
|
||||
std::ostream &operator<<(std::ostream& out, const std::error_condition& err);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <android/log.h>
|
||||
|
@ -101,7 +106,7 @@ struct t_RsLogger
|
|||
/**
|
||||
* Comfortable debug message loggin, supports chaining like std::cerr but can
|
||||
* be easly and selectively disabled at compile time to reduce generated binary
|
||||
* size and performance impact without too many #ifdef around.
|
||||
* size and performance impact without too many \#ifdef around.
|
||||
*
|
||||
* To selectively debug your context you can just add something like this in
|
||||
* in that context, as an example for a class you can just add a line like this
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright (C) 2004-2007 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2016-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2016-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2019-2020 Asociación Civil Altermundi <info@altermundi.net> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
|
@ -23,7 +23,7 @@
|
|||
*******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
#include <ctime>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
|
@ -95,6 +95,9 @@ void RsThread::resetTid()
|
|||
}
|
||||
|
||||
RsThread::RsThread() : mHasStopped(true), mShouldStop(false), mLastTid()
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
, mStopTimeout(0)
|
||||
#endif
|
||||
{ resetTid(); }
|
||||
|
||||
bool RsThread::isRunning() { return !mHasStopped; }
|
||||
|
@ -117,6 +120,10 @@ void RsThread::wrapRun()
|
|||
|
||||
void RsThread::fullstop()
|
||||
{
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
const rstime_t stopRequTS = time(nullptr);
|
||||
#endif
|
||||
|
||||
askForStop();
|
||||
|
||||
const pthread_t callerTid = pthread_self();
|
||||
|
@ -141,6 +148,32 @@ void RsThread::fullstop()
|
|||
RsDbg() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed"
|
||||
<< " waiting for thread: " << std::hex << mLastTid
|
||||
<< std::dec << " " << mFullName << " to stop" << std::endl;
|
||||
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
if(mStopTimeout && time(nullptr) > stopRequTS + mStopTimeout)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " thread mLastTid: " << std::hex
|
||||
<< mLastTid << " mTid: " << mTid << std::dec << " "
|
||||
<< mFullName
|
||||
<< " ignored our nice stop request for more then "
|
||||
<< mStopTimeout
|
||||
<< " seconds, will be forcefully stopped. "
|
||||
<< "Please submit a report to RetroShare developers"
|
||||
<< std::endl;
|
||||
|
||||
const auto terr = pthread_cancel(mTid);
|
||||
if(terr == 0) mHasStopped = true;
|
||||
else
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " pthread_cancel("
|
||||
<< std::hex << mTid << std::dec <<") returned "
|
||||
<< terr << " " << rsErrnoName(terr) << std::endl;
|
||||
print_stacktrace();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif // def RS_THREAD_FORCE_STOP
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#include "util/rsmemory.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
# include "util/rstime.h"
|
||||
#endif
|
||||
|
||||
//#define RSMUTEX_DEBUG
|
||||
|
||||
|
@ -249,6 +252,13 @@ protected:
|
|||
* of this method, @see JsonApiServer for an usage example. */
|
||||
virtual void onStopRequested() {}
|
||||
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
/** Set last resort timeout to forcefully kill thread if it didn't stop
|
||||
* nicely, one should never use this, still we needed to introduce this
|
||||
* to investigate some bugs in external libraries */
|
||||
void setStopTimeout(rstime_t timeout) { mStopTimeout = timeout; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
/** Call @see run() setting the appropriate flags around it*/
|
||||
void wrapRun();
|
||||
|
@ -277,6 +287,11 @@ private:
|
|||
* and that might happens concurrently (or just before) a debug message
|
||||
* being printed, thus causing the debug message to print a mangled value.*/
|
||||
pthread_t mLastTid;
|
||||
|
||||
#ifdef RS_THREAD_FORCE_STOP
|
||||
/// @see setStopTimeout
|
||||
rstime_t mStopTimeout;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue