[UI] Correct a crash due to concurrent accesses to a dbo session
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include <Wt/Http/Response>
|
#include <Wt/Http/Response>
|
||||||
|
|
||||||
#include "logger/Logger.hpp"
|
#include "logger/Logger.hpp"
|
||||||
|
#include "LmsApplication.hpp"
|
||||||
|
|
||||||
#include "cover/CoverArtGrabber.hpp"
|
#include "cover/CoverArtGrabber.hpp"
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ _db(db)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CoverResource:: ~CoverResource()
|
CoverResource::~CoverResource()
|
||||||
{
|
{
|
||||||
beingDeleted();
|
beingDeleted();
|
||||||
}
|
}
|
||||||
@@ -121,7 +122,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
|
|
||||||
{
|
{
|
||||||
// transactions are not thread safe
|
// transactions are not thread safe
|
||||||
std::unique_lock<std::mutex> lock(_mutex);
|
Wt::WApplication::UpdateLock lock(LmsApplication::instance());
|
||||||
|
|
||||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||||
|
|
||||||
@@ -147,8 +148,9 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
else if (releaseIdStr)
|
else if (releaseIdStr)
|
||||||
{
|
{
|
||||||
Database::Release::id_type releaseId = std::stol(*releaseIdStr);
|
Database::Release::id_type releaseId = std::stol(*releaseIdStr);
|
||||||
|
|
||||||
// transactions are not thread safe
|
// transactions are not thread safe
|
||||||
std::unique_lock<std::mutex> lock(_mutex);
|
Wt::WApplication::UpdateLock lock(LmsApplication::instance());
|
||||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||||
|
|
||||||
covers = CoverArt::Grabber::instance().getFromRelease(_db.getSession(), releaseId);
|
covers = CoverArt::Grabber::instance().getFromRelease(_db.getSession(), releaseId);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class CoverResource : public Wt::WResource
|
|||||||
Image::Image getDefaultCover(std::size_t size);
|
Image::Image getDefaultCover(std::size_t size);
|
||||||
void putCover(Wt::Http::Response& response, Image::Image image);
|
void putCover(Wt::Http::Response& response, Image::Image image);
|
||||||
|
|
||||||
|
// Used to protect transactions since they are not thread safe
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
Database::Handler& _db;
|
Database::Handler& _db;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <Wt/Http/Response>
|
#include <Wt/Http/Response>
|
||||||
|
|
||||||
#include "logger/Logger.hpp"
|
#include "logger/Logger.hpp"
|
||||||
|
#include "LmsApplication.hpp"
|
||||||
|
|
||||||
#include "TranscodeResource.hpp"
|
#include "TranscodeResource.hpp"
|
||||||
|
|
||||||
@@ -94,41 +95,41 @@ TranscodeResource::handleRequest(const Wt::Http::Request& request,
|
|||||||
Database::Track::id_type trackId = std::stol(*trackIdStr);
|
Database::Track::id_type trackId = std::stol(*trackIdStr);
|
||||||
|
|
||||||
// transactions are not thread safe
|
// transactions are not thread safe
|
||||||
std::unique_lock<std::mutex> lock(_mutex);
|
|
||||||
|
|
||||||
Wt::Dbo::Transaction transaction(_db.getSession());
|
|
||||||
|
|
||||||
Database::User::pointer user = _db.getCurrentUser();
|
|
||||||
Database::Track::pointer track = Database::Track::getById(_db.getSession(), trackId);
|
|
||||||
|
|
||||||
if (!track)
|
|
||||||
{
|
{
|
||||||
LMS_LOG(UI, ERROR) << "Missing track";
|
Wt::WApplication::UpdateLock lock(LmsApplication::instance());
|
||||||
return;
|
|
||||||
|
Wt::Dbo::Transaction transaction(_db.getSession());
|
||||||
|
|
||||||
|
Database::User::pointer user = _db.getCurrentUser();
|
||||||
|
Database::Track::pointer track = Database::Track::getById(_db.getSession(), trackId);
|
||||||
|
|
||||||
|
if (!track)
|
||||||
|
{
|
||||||
|
LMS_LOG(UI, ERROR) << "Missing track";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
{
|
||||||
|
LMS_LOG(UI, ERROR) << "Missing user";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Av::TranscodeParameters parameters;
|
||||||
|
|
||||||
|
parameters.setOffset(boost::posix_time::seconds(std::stol(*offsetStr)));
|
||||||
|
parameters.setEncoding(Av::encoding_from_int(std::stol(*encodingStr)));
|
||||||
|
parameters.setBitrate(Av::Stream::Type::Audio, user->getAudioBitrate() );
|
||||||
|
for (std::string strStream: streams)
|
||||||
|
{
|
||||||
|
LMS_LOG(UI, DEBUG) << "Added stream " << std::stol(strStream);
|
||||||
|
parameters.addStream(std::stol(strStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
LMS_LOG(UI, DEBUG) << "Offset set to " << parameters.getOffset();
|
||||||
|
transcoder = std::make_shared<Av::Transcoder>(track->getPath(), parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
LMS_LOG(UI, ERROR) << "Missing user";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Av::TranscodeParameters parameters;
|
|
||||||
|
|
||||||
parameters.setOffset(boost::posix_time::seconds(std::stol(*offsetStr)));
|
|
||||||
parameters.setEncoding(Av::encoding_from_int(std::stol(*encodingStr)));
|
|
||||||
parameters.setBitrate(Av::Stream::Type::Audio, user->getAudioBitrate() );
|
|
||||||
for (std::string strStream: streams)
|
|
||||||
{
|
|
||||||
LMS_LOG(UI, DEBUG) << "Added stream " << std::stol(strStream);
|
|
||||||
parameters.addStream(std::stol(strStream));
|
|
||||||
}
|
|
||||||
|
|
||||||
LMS_LOG(UI, DEBUG) << "Offset set to " << parameters.getOffset();
|
|
||||||
transcoder = std::make_shared<Av::Transcoder>(track->getPath(), parameters);
|
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
LMS_LOG(UI, DEBUG) << "Mime type set to '" << Av::encoding_to_mimetype(Av::Encoding::MP3);
|
LMS_LOG(UI, DEBUG) << "Mime type set to '" << Av::encoding_to_mimetype(Av::Encoding::MP3);
|
||||||
response.setMimeType( Av::encoding_to_mimetype(Av::Encoding::MP3) );
|
response.setMimeType( Av::encoding_to_mimetype(Av::Encoding::MP3) );
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ class TranscodeResource : public Wt::WResource
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex _mutex;
|
|
||||||
Database::Handler& _db;
|
Database::Handler& _db;
|
||||||
|
|
||||||
static const std::size_t _bufferSize = 65536;
|
static const std::size_t _bufferSize = 65536;
|
||||||
|
|||||||
Reference in New Issue
Block a user