From 18a979a67ae2f88ef424a45a39b7b84c2ea24b4f Mon Sep 17 00:00:00 2001 From: emeric Date: Wed, 13 Jan 2016 19:03:53 +0100 Subject: [PATCH] [UI] Correct a crash due to concurrent accesses to a dbo session --- src/ui/resource/CoverResource.cpp | 8 ++-- src/ui/resource/CoverResource.hpp | 1 + src/ui/resource/TranscodeResource.cpp | 65 ++++++++++++++------------- src/ui/resource/TranscodeResource.hpp | 1 - 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/ui/resource/CoverResource.cpp b/src/ui/resource/CoverResource.cpp index 885ad94b..54e03972 100644 --- a/src/ui/resource/CoverResource.cpp +++ b/src/ui/resource/CoverResource.cpp @@ -21,6 +21,7 @@ #include #include "logger/Logger.hpp" +#include "LmsApplication.hpp" #include "cover/CoverArtGrabber.hpp" @@ -36,7 +37,7 @@ _db(db) { } -CoverResource:: ~CoverResource() +CoverResource::~CoverResource() { beingDeleted(); } @@ -121,7 +122,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons { // transactions are not thread safe - std::unique_lock lock(_mutex); + Wt::WApplication::UpdateLock lock(LmsApplication::instance()); Wt::Dbo::Transaction transaction(_db.getSession()); @@ -147,8 +148,9 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons else if (releaseIdStr) { Database::Release::id_type releaseId = std::stol(*releaseIdStr); + // transactions are not thread safe - std::unique_lock lock(_mutex); + Wt::WApplication::UpdateLock lock(LmsApplication::instance()); Wt::Dbo::Transaction transaction(_db.getSession()); covers = CoverArt::Grabber::instance().getFromRelease(_db.getSession(), releaseId); diff --git a/src/ui/resource/CoverResource.hpp b/src/ui/resource/CoverResource.hpp index abd14cd0..9a8ee139 100644 --- a/src/ui/resource/CoverResource.hpp +++ b/src/ui/resource/CoverResource.hpp @@ -51,6 +51,7 @@ class CoverResource : public Wt::WResource Image::Image getDefaultCover(std::size_t size); void putCover(Wt::Http::Response& response, Image::Image image); + // Used to protect transactions since they are not thread safe std::mutex _mutex; Database::Handler& _db; diff --git a/src/ui/resource/TranscodeResource.cpp b/src/ui/resource/TranscodeResource.cpp index 16478a5f..b0a31482 100644 --- a/src/ui/resource/TranscodeResource.cpp +++ b/src/ui/resource/TranscodeResource.cpp @@ -20,6 +20,7 @@ #include #include "logger/Logger.hpp" +#include "LmsApplication.hpp" #include "TranscodeResource.hpp" @@ -94,41 +95,41 @@ TranscodeResource::handleRequest(const Wt::Http::Request& request, Database::Track::id_type trackId = std::stol(*trackIdStr); // transactions are not thread safe - std::unique_lock 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"; - return; + Wt::WApplication::UpdateLock lock(LmsApplication::instance()); + + 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(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(track->getPath(), parameters); - - transaction.commit(); - LMS_LOG(UI, DEBUG) << "Mime type set to '" << Av::encoding_to_mimetype(Av::Encoding::MP3); response.setMimeType( Av::encoding_to_mimetype(Av::Encoding::MP3) ); diff --git a/src/ui/resource/TranscodeResource.hpp b/src/ui/resource/TranscodeResource.hpp index e4714250..2fc2ad1d 100644 --- a/src/ui/resource/TranscodeResource.hpp +++ b/src/ui/resource/TranscodeResource.hpp @@ -42,7 +42,6 @@ class TranscodeResource : public Wt::WResource private: - std::mutex _mutex; Database::Handler& _db; static const std::size_t _bufferSize = 65536;