mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-26 23:36:59 -05:00
Merge upstream
This commit is contained in:
commit
2b2a9f9a89
@ -146,6 +146,7 @@ bool RsJsonApi::parseToken(
|
||||
|
||||
JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
mService(std::make_shared<restbed::Service>()),
|
||||
mServiceMutex("JsonApiServer restbed ptr"),
|
||||
mListeningPort(RsJsonApi::DEFAULT_PORT),
|
||||
mBindingAddress(RsJsonApi::DEFAULT_BINDING_ADDRESS)
|
||||
{
|
||||
@ -223,7 +224,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
rsLoginHelper->attemptLogin(account, password);
|
||||
|
||||
if( retval == RsInit::OK )
|
||||
authorizeUser(account.toStdString(),password);
|
||||
authorizeUser(account.toStdString(), password);
|
||||
|
||||
// serialize out parameters and return value to JSON
|
||||
{
|
||||
@ -310,6 +311,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
registerHandler("/rsEvents/registerEventsHandler",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
const std::weak_ptr<rb::Service> weakService(mService);
|
||||
const std::multimap<std::string, std::string> headers
|
||||
{
|
||||
{ "Connection", "keep-alive" },
|
||||
@ -319,7 +321,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
|
||||
size_t reqSize = static_cast<size_t>(
|
||||
session->get_request()->get_header("Content-Length", 0) );
|
||||
session->fetch( reqSize, [this](
|
||||
session->fetch( reqSize, [weakService](
|
||||
const std::shared_ptr<rb::Session> session,
|
||||
const rb::Bytes& body )
|
||||
{
|
||||
@ -332,9 +334,17 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
const std::weak_ptr<rb::Session> weakSession(session);
|
||||
RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId();
|
||||
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback =
|
||||
[this, weakSession, hId](std::shared_ptr<const RsEvent> event)
|
||||
[weakSession, weakService, hId](
|
||||
std::shared_ptr<const RsEvent> event )
|
||||
{
|
||||
mService->schedule( [weakSession, hId, event]()
|
||||
auto lService = weakService.lock();
|
||||
if(!lService || lService->is_down())
|
||||
{
|
||||
if(rsEvents) rsEvents->unregisterEventsHandler(hId);
|
||||
return;
|
||||
}
|
||||
|
||||
lService->schedule( [weakSession, hId, event]()
|
||||
{
|
||||
auto session = weakSession.lock();
|
||||
if(!session || session->is_closed())
|
||||
@ -500,10 +510,10 @@ bool JsonApiServer::authorizeUser(
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!librs::util::is_alphanumeric(passwd))
|
||||
if(passwd.empty())
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Password is not alphanumeric"
|
||||
<< std::endl;
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " Password is empty, are you sure "
|
||||
<< "this what you wanted?" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -581,21 +591,21 @@ std::vector<std::shared_ptr<rb::Resource> > JsonApiServer::getResources() const
|
||||
return tab;
|
||||
}
|
||||
|
||||
bool JsonApiServer::restart()
|
||||
void JsonApiServer::restart()
|
||||
{
|
||||
fullstop();
|
||||
RsThread::start("JSON API Server");
|
||||
|
||||
return true;
|
||||
/* It is important to wrap into async(...) because fullstop() method can't
|
||||
* be called from same thread of execution hence from JSON API thread! */
|
||||
RsThread::async([this]()
|
||||
{
|
||||
fullstop();
|
||||
RsThread::start("JSON API Server");
|
||||
});
|
||||
}
|
||||
|
||||
void JsonApiServer::onStopRequested()
|
||||
{ if(mService->is_up()) mService->stop(); }
|
||||
|
||||
bool JsonApiServer::fullstop()
|
||||
{
|
||||
RsThread::fullstop();
|
||||
return true;
|
||||
RS_STACK_MUTEX(mServiceMutex);
|
||||
mService->stop();
|
||||
}
|
||||
|
||||
uint16_t JsonApiServer::listeningPort() const { return mListeningPort; }
|
||||
@ -611,16 +621,12 @@ void JsonApiServer::run()
|
||||
settings->set_bind_address(mBindingAddress);
|
||||
settings->set_default_header("Connection", "close");
|
||||
|
||||
if(mService->is_up())
|
||||
{
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " restbed is already running. "
|
||||
<< " stopping it before starting again!" << std::endl;
|
||||
mService->stop();
|
||||
}
|
||||
|
||||
/* re-allocating mService is important because it deletes the existing
|
||||
* service and therefore leaves the listening port open */
|
||||
mService = std::make_shared<restbed::Service>();
|
||||
{
|
||||
RS_STACK_MUTEX(mServiceMutex);
|
||||
mService = std::make_shared<restbed::Service>();
|
||||
}
|
||||
|
||||
for(auto& r: getResources()) mService->publish(r);
|
||||
|
||||
@ -628,8 +634,8 @@ void JsonApiServer::run()
|
||||
{
|
||||
RsUrl apiUrl; apiUrl.setScheme("http").setHost(mBindingAddress)
|
||||
.setPort(mListeningPort);
|
||||
RsDbg() << __PRETTY_FUNCTION__ << " JSON API server listening on "
|
||||
<< apiUrl.toString() << std::endl;
|
||||
RsInfo() << __PRETTY_FUNCTION__ << " JSON API server listening on "
|
||||
<< apiUrl.toString() << std::endl;
|
||||
mService->start(settings);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
@ -640,7 +646,7 @@ void JsonApiServer::run()
|
||||
return;
|
||||
}
|
||||
|
||||
RsInfo() << __PRETTY_FUNCTION__ << " finished!" << std::endl;
|
||||
RsDbg() << __PRETTY_FUNCTION__ << " finished!" << std::endl;
|
||||
}
|
||||
|
||||
/*static*/ void RsJsonApi::version(
|
||||
|
@ -63,10 +63,13 @@ public:
|
||||
std::vector<std::shared_ptr<rb::Resource>> getResources() const;
|
||||
|
||||
/// @see RsJsonApi
|
||||
bool restart() override;
|
||||
void fullstop() override { RsThread::fullstop(); }
|
||||
|
||||
/// @see RsJsonApi
|
||||
bool fullstop() override;
|
||||
void restart() override;
|
||||
|
||||
/// @see RsJsonApi
|
||||
void askForStop() override { RsThread::askForStop(); }
|
||||
|
||||
/// @see RsJsonApi
|
||||
inline bool isRunning() override { return RsThread::isRunning(); }
|
||||
@ -193,6 +196,10 @@ private:
|
||||
std::less<const JsonApiResourceProvider> > mResourceProviders;
|
||||
|
||||
std::shared_ptr<restbed::Service> mService;
|
||||
/** Protect service only during very critical operation like resetting the
|
||||
* pointer, still not 100% thread safe, but hopefully we can avoid
|
||||
* crashes/freeze with this */
|
||||
RsMutex mServiceMutex;
|
||||
|
||||
uint16_t mListeningPort;
|
||||
std::string mBindingAddress;
|
||||
|
@ -43,18 +43,25 @@ public:
|
||||
static const std::string DEFAULT_BINDING_ADDRESS; // 127.0.0.1
|
||||
|
||||
/**
|
||||
* @brief Restart RsJsonApi server
|
||||
* @brief Restart RsJsonApi server asynchronously.
|
||||
* @jsonapi{development}
|
||||
*/
|
||||
virtual bool restart() = 0;
|
||||
virtual void restart() = 0;
|
||||
|
||||
/** @brief Request RsJsonApi to stop and wait until it has stopped.
|
||||
* Do not expose this method to JSON API as fullstop must not be called from
|
||||
* the same thread of service execution.
|
||||
*/
|
||||
virtual void fullstop() = 0;
|
||||
|
||||
/**
|
||||
* @brief Request RsJsonApi to stop and wait until ti has stopped.
|
||||
* @brief Request RsJsonApi to stop asynchronously.
|
||||
* @jsonapi{development}
|
||||
* Be expecially carefull to call this from JSON API because you will loose
|
||||
* access to the API.
|
||||
* @jsonapi{development}
|
||||
* If you need to wait until stopping has completed @see isRunning().
|
||||
*/
|
||||
virtual bool fullstop() = 0;
|
||||
virtual void askForStop() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get status of the json api server
|
||||
@ -128,8 +135,7 @@ public:
|
||||
std::string& user, std::string& passwd );
|
||||
|
||||
/**
|
||||
* Add new auth (user,passwd) token to the authorized set, creating the
|
||||
* token user:passwd internally.
|
||||
* Add new API auth (user,passwd) token to the authorized set.
|
||||
* @jsonapi{development}
|
||||
* @param[in] user user name to autorize, must be alphanumerinc
|
||||
* @param[in] password password for the user, must be alphanumerinc
|
||||
|
@ -247,7 +247,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||
if (msgChange)
|
||||
{
|
||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW)
|
||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED)
|
||||
{
|
||||
/* message received */
|
||||
if (rsEvents)
|
||||
|
@ -501,7 +501,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
RsGxsCircleDetails details;
|
||||
getCircleDetails(circle_id,details);
|
||||
|
||||
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
|
||||
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) )
|
||||
for (auto msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt)
|
||||
{
|
||||
RsGxsCircleMsg msg;
|
||||
|
@ -191,7 +191,7 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||
if (msgChange)
|
||||
{
|
||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) /* message received */
|
||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
|
||||
if (rsEvents)
|
||||
{
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
|
||||
|
@ -112,7 +112,7 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
// It could be taken a step further and directly request these msgs for an update.
|
||||
addGroupForProcessing(mit->first);
|
||||
|
||||
if (rsEvents && msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW)
|
||||
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
|
@ -207,15 +207,14 @@ bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest)
|
||||
|
||||
bool is_alphanumeric(char c)
|
||||
{
|
||||
return (c>='0' && c<'9') || (c>='a' && c<='z') || (c>='A' && c<='Z') ;
|
||||
return (c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z');
|
||||
}
|
||||
|
||||
bool is_alphanumeric(const std::string& s)
|
||||
{
|
||||
for(uint32_t i=0;i<s.size();++i)
|
||||
if(!is_alphanumeric(s[i]))
|
||||
return false;
|
||||
return true;
|
||||
for( uint32_t i=0; i < s.size(); ++i)
|
||||
if(!is_alphanumeric(s[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} } // librs::util
|
||||
|
@ -85,7 +85,7 @@ int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RsThread::RsThread() : mHasStopped(true), mShouldStop(false)
|
||||
void RsThread::resetTid()
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
memset (&mTid, 0, sizeof(mTid));
|
||||
@ -94,6 +94,9 @@ RsThread::RsThread() : mHasStopped(true), mShouldStop(false)
|
||||
#endif
|
||||
}
|
||||
|
||||
RsThread::RsThread() : mHasStopped(true), mShouldStop(false), mLastTid()
|
||||
{ resetTid(); }
|
||||
|
||||
bool RsThread::isRunning() { return !mHasStopped; }
|
||||
|
||||
bool RsThread::shouldStop() { return mShouldStop; }
|
||||
@ -102,13 +105,13 @@ void RsThread::askForStop()
|
||||
{
|
||||
/* Call onStopRequested() only once even if askForStop() is called multiple
|
||||
* times */
|
||||
if(!mShouldStop.exchange(true))
|
||||
RsThread::async([&](){ onStopRequested(); });
|
||||
if(!mShouldStop.exchange(true)) onStopRequested();
|
||||
}
|
||||
|
||||
void RsThread::wrapRun()
|
||||
{
|
||||
run();
|
||||
resetTid();
|
||||
mHasStopped = true;
|
||||
}
|
||||
|
||||
@ -122,7 +125,8 @@ void RsThread::fullstop()
|
||||
RsErr() << __PRETTY_FUNCTION__ << " called by same thread. This should "
|
||||
<< "never happen! this: " << static_cast<void*>(this)
|
||||
<< std::hex << ", callerTid: " << callerTid
|
||||
<< ", mTid: " << mTid << std::dec << std::endl;
|
||||
<< ", mTid: " << mTid << std::dec
|
||||
<< ", mFullName: " << mFullName << std::endl;
|
||||
print_stacktrace();
|
||||
return;
|
||||
}
|
||||
@ -134,9 +138,9 @@ void RsThread::fullstop()
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
++i;
|
||||
if(!(i%5))
|
||||
RsInfo() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed"
|
||||
<< " waiting for thread: " << mTid << " " << mFullName
|
||||
<< " to stop" << std::endl;
|
||||
RsDbg() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed"
|
||||
<< " waiting for thread: " << std::hex << mLastTid
|
||||
<< std::dec << " " << mFullName << " to stop" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +162,9 @@ bool RsThread::start(const std::string& threadName)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Store an extra copy of thread id for debugging */
|
||||
mLastTid = mTid;
|
||||
|
||||
/* Store thread full name as PThread is not able to keep it entirely */
|
||||
mFullName = threadName;
|
||||
|
||||
@ -266,10 +273,10 @@ double RsStackMutex::getCurrentTS()
|
||||
|
||||
RsThread::~RsThread()
|
||||
{
|
||||
if(isRunning())
|
||||
if(!mHasStopped)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mTid << " "
|
||||
<< mFullName << " that is still "
|
||||
RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mLastTid
|
||||
<< " " << mFullName << " that is still "
|
||||
<< "running! Something seems very wrong here and RetroShare is "
|
||||
<< "likely to crash because of this." << std::endl;
|
||||
print_stacktrace();
|
||||
|
@ -264,9 +264,19 @@ private:
|
||||
|
||||
/// Store the id of the corresponding pthread
|
||||
pthread_t mTid;
|
||||
void resetTid();
|
||||
|
||||
/// Store thread full name
|
||||
/** Store thread full name for debugging because PThread is limited to 15
|
||||
* char thread names */
|
||||
std::string mFullName;
|
||||
|
||||
/** Store a copy of thread id which is never reset to 0 after initialization
|
||||
* due to RsThread functioning. After RsThread initialization this member is
|
||||
* only re-written with a new tread id in start(...).
|
||||
* This is useful for debugging because mTid is reset at the end of wrapRun
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user