Solving issue 1684: "thumbnail.cc uses Glib::Mutex recusively" ; this changeset introduce a new MyMutex and MyMutex::MyLock class that has to be used instead of Glib ones
This commit is contained in:
parent
987e4dcd89
commit
f512d74323
@ -73,6 +73,7 @@ option (WITH_BZIP "Build with Bzip2 support" ON)
|
|||||||
option (WITH_MYFILE_MMAP "Build using memory mapped file" ON)
|
option (WITH_MYFILE_MMAP "Build using memory mapped file" ON)
|
||||||
option (OPTION_OMP "Build with OpenMP support" ON)
|
option (OPTION_OMP "Build with OpenMP support" ON)
|
||||||
option (PROTECT_VECTORS "Protect critical vectors by custom R/W Mutex, recommanded even if your std::vector is thread safe" ON)
|
option (PROTECT_VECTORS "Protect critical vectors by custom R/W Mutex, recommanded even if your std::vector is thread safe" ON)
|
||||||
|
option (STRICT_MUTEX "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" ON)
|
||||||
option (TRACE_MYRWMUTEX "Trace RT's custom R/W Mutex (Debug builds only); redirecting std::out to a file is strongly recommended!" OFF)
|
option (TRACE_MYRWMUTEX "Trace RT's custom R/W Mutex (Debug builds only); redirecting std::out to a file is strongly recommended!" OFF)
|
||||||
option (AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF)
|
option (AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF)
|
||||||
|
|
||||||
@ -162,6 +163,13 @@ if (NOT BUILD_BUNDLE AND
|
|||||||
message (FATAL_ERROR "The paths has to be absolute or use -DBUILD_BUNDLE=ON")
|
message (FATAL_ERROR "The paths has to be absolute or use -DBUILD_BUNDLE=ON")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# MyMutex
|
||||||
|
if (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||||
|
add_definitions (-DSTRICT_MUTEX=1)
|
||||||
|
else (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||||
|
add_definitions (-DSTRICT_MUTEX=0)
|
||||||
|
endif (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
||||||
|
|
||||||
# MyRWMutex
|
# MyRWMutex
|
||||||
if (PROTECT_VECTORS)
|
if (PROTECT_VECTORS)
|
||||||
add_definitions (-DPROTECT_VECTORS=1)
|
add_definitions (-DPROTECT_VECTORS=1)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
//#include "bilateral2.h"
|
//#include "bilateral2.h"
|
||||||
#include "gauss.h"
|
#include "gauss.h"
|
||||||
@ -87,8 +88,8 @@ namespace rtengine {
|
|||||||
|
|
||||||
void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp)
|
void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp)
|
||||||
{
|
{
|
||||||
static Glib::Mutex FftwMutex;
|
static MyMutex FftwMutex;
|
||||||
Glib::Mutex::Lock lock(FftwMutex);
|
MyMutex::MyLock lock(FftwMutex);
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
// Aligned buffer that should be faster
|
// Aligned buffer that should be faster
|
||||||
template <class T> class AlignedBuffer {
|
template <class T> class AlignedBuffer {
|
||||||
@ -107,7 +108,7 @@ public:
|
|||||||
// Multi processor version, use with OpenMP
|
// Multi processor version, use with OpenMP
|
||||||
template <class T> class AlignedBufferMP {
|
template <class T> class AlignedBufferMP {
|
||||||
private:
|
private:
|
||||||
Glib::Mutex mtx;
|
MyMutex mtx;
|
||||||
std::vector<AlignedBuffer<T>*> buffers;
|
std::vector<AlignedBuffer<T>*> buffers;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
AlignedBuffer<T>* acquire() {
|
AlignedBuffer<T>* acquire() {
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
// Find available buffer
|
// Find available buffer
|
||||||
for (int i;i<buffers.size();i++) {
|
for (int i;i<buffers.size();i++) {
|
||||||
@ -139,7 +140,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void release(AlignedBuffer<T>* buffer) {
|
void release(AlignedBuffer<T>* buffer) {
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
buffer->inUse=false;
|
buffer->inUse=false;
|
||||||
}
|
}
|
||||||
|
@ -556,17 +556,17 @@ namespace rtengine {
|
|||||||
for (int i=0; i<m_h2; i++) {
|
for (int i=0; i<m_h2; i++) {
|
||||||
|
|
||||||
if (subsamp_out) {
|
if (subsamp_out) {
|
||||||
SynthesisFilterSubsamp (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi, \
|
SynthesisFilterSubsamp (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi,
|
||||||
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
||||||
SynthesisFilterSubsamp (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi, \
|
SynthesisFilterSubsamp (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi,
|
||||||
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
||||||
//SynthesisFilterSubsampHaar (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, 1, m_w);//TODO: this is buggy
|
//SynthesisFilterSubsampHaar (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, 1, m_w);//TODO: this is buggy
|
||||||
//SynthesisFilterSubsampHaar (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, 1, m_w);
|
//SynthesisFilterSubsampHaar (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, 1, m_w);
|
||||||
} else {
|
} else {
|
||||||
//SynthesisFilter (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi, \
|
//SynthesisFilter (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi,
|
||||||
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
// filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
||||||
//SynthesisFilter (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi, \
|
//SynthesisFilter (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi,
|
||||||
filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
// filterH, filterH+taps, taps, offset, 1/*pitch*/, m_w/*dstlen*/);
|
||||||
SynthesisFilterHaar (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi, 1, m_w);
|
SynthesisFilterHaar (wavcoeffs[0]+i*m_w2, wavcoeffs[1]+i*m_w2, tmpLo+i*m_w, bufferLo, bufferHi, 1, m_w);
|
||||||
SynthesisFilterHaar (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi, 1, m_w);
|
SynthesisFilterHaar (wavcoeffs[2]+i*m_w2, wavcoeffs[3]+i*m_w2, tmpHi+i*m_w, bufferLo, bufferHi, 1, m_w);
|
||||||
}
|
}
|
||||||
@ -576,12 +576,12 @@ namespace rtengine {
|
|||||||
//OpenMP here
|
//OpenMP here
|
||||||
for (int j=0; j<m_w; j++) {
|
for (int j=0; j<m_w; j++) {
|
||||||
if (subsamp_out) {
|
if (subsamp_out) {
|
||||||
SynthesisFilterSubsamp (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi, \
|
SynthesisFilterSubsamp (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi,
|
||||||
filterV, filterV+taps, taps, offset, m_w/*pitch*/, m_h/*dstlen*/);
|
filterV, filterV+taps, taps, offset, m_w/*pitch*/, m_h/*dstlen*/);
|
||||||
//SynthesisFilterSubsampHaar (tmpLo+j, tmpHi+j, dst+j, m_w, m_h);
|
//SynthesisFilterSubsampHaar (tmpLo+j, tmpHi+j, dst+j, m_w, m_h);
|
||||||
} else {
|
} else {
|
||||||
//SynthesisFilter (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi, \
|
//SynthesisFilter (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi,
|
||||||
filterV, filterV+taps, taps, offset, m_w/*pitch*/, m_h/*dstlen*/);
|
// filterV, filterV+taps, taps, offset, m_w/*pitch*/, m_h/*dstlen*/);
|
||||||
SynthesisFilterHaar (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi, m_w, m_h);
|
SynthesisFilterHaar (tmpLo+j, tmpHi+j, dst+j, bufferLo, bufferHi, m_w, m_h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ DCPProfile::DCPProfile(Glib::ustring fname, bool isRTProfile) {
|
|||||||
|
|
||||||
TagDirectory *tagDir=ExifManager::parseTIFF(pFile, false);
|
TagDirectory *tagDir=ExifManager::parseTIFF(pFile, false);
|
||||||
|
|
||||||
Tag* tag = tagDir->getTag(TagCalibrationIlluminant1); iLightSource1 = (tag!=NULL ? tag->toInt(0,SHORT) : -1);
|
Tag* tag = tagDir->getTag(TagCalibrationIlluminant1); iLightSource1 = (tag!=NULL ? tag->toInt(0,rtexif::SHORT) : -1);
|
||||||
tag = tagDir->getTag(TagCalibrationIlluminant2); iLightSource2 = (tag!=NULL ? tag->toInt(0,SHORT) : -1);
|
tag = tagDir->getTag(TagCalibrationIlluminant2); iLightSource2 = (tag!=NULL ? tag->toInt(0,rtexif::SHORT) : -1);
|
||||||
|
|
||||||
bool hasSecondHueSat = tagDir->getTag(TagProfileHueSatMapData2)!=NULL; // some profiles have two matrices, but just one huesat
|
bool hasSecondHueSat = tagDir->getTag(TagProfileHueSatMapData2)!=NULL; // some profiles have two matrices, but just one huesat
|
||||||
|
|
||||||
@ -495,8 +495,8 @@ DCPStore* DCPStore::getInstance()
|
|||||||
static DCPStore* instance_ = 0;
|
static DCPStore* instance_ = 0;
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
instance_ = new DCPStore();
|
instance_ = new DCPStore();
|
||||||
@ -507,7 +507,7 @@ DCPStore* DCPStore::getInstance()
|
|||||||
|
|
||||||
// Reads all profiles from the given profiles dir
|
// Reads all profiles from the given profiles dir
|
||||||
void DCPStore::init (Glib::ustring rtProfileDir) {
|
void DCPStore::init (Glib::ustring rtProfileDir) {
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
fileStdProfiles.clear();
|
fileStdProfiles.clear();
|
||||||
|
|
||||||
@ -550,7 +550,7 @@ void DCPStore::init (Glib::ustring rtProfileDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DCPProfile* DCPStore::getProfile (Glib::ustring filename, bool isRTProfile) {
|
DCPProfile* DCPStore::getProfile (Glib::ustring filename, bool isRTProfile) {
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
std::map<Glib::ustring, DCPProfile*>::iterator r = profileCache.find (filename);
|
std::map<Glib::ustring, DCPProfile*>::iterator r = profileCache.find (filename);
|
||||||
if (r!=profileCache.end()) return r->second;
|
if (r!=profileCache.end()) return r->second;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -65,7 +66,7 @@ namespace rtengine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class DCPStore {
|
class DCPStore {
|
||||||
Glib::Mutex mtx;
|
MyMutex mtx;
|
||||||
|
|
||||||
// these contain standard profiles from RT. keys are all in uppercase, file path is value
|
// these contain standard profiles from RT. keys are all in uppercase, file path is value
|
||||||
std::map<Glib::ustring, Glib::ustring> fileStdProfiles;
|
std::map<Glib::ustring, Glib::ustring> fileStdProfiles;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
/*
|
|
||||||
/*
|
/*
|
||||||
* This file is part of RawTherapee.
|
* This file is part of RawTherapee.
|
||||||
*
|
*
|
||||||
@ -55,13 +54,13 @@ Crop::~Crop () {
|
|||||||
void Crop::setListener (DetailedCropListener* il) {
|
void Crop::setListener (DetailedCropListener* il) {
|
||||||
// We can make reads in the IF, because the mProcessing lock is only needed for change
|
// We can make reads in the IF, because the mProcessing lock is only needed for change
|
||||||
if (cropImageListener!=il) {
|
if (cropImageListener!=il) {
|
||||||
Glib::Mutex::Lock lock(cropMutex);
|
MyMutex::MyLock lock(cropMutex);
|
||||||
cropImageListener = il;
|
cropImageListener = il;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Crop::update (int todo) {
|
void Crop::update (int todo) {
|
||||||
Glib::Mutex::Lock lock(cropMutex);
|
MyMutex::MyLock lock(cropMutex);
|
||||||
|
|
||||||
ProcParams& params = parent->params;
|
ProcParams& params = parent->params;
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ void Crop::update (int todo) {
|
|||||||
bool needstransform = parent->ipf.needsTransform();
|
bool needstransform = parent->ipf.needsTransform();
|
||||||
|
|
||||||
if (todo & (M_INIT|M_LINDENOISE)) {
|
if (todo & (M_INIT|M_LINDENOISE)) {
|
||||||
Glib::Mutex::Lock lock(parent->minit); // Also used in improccoord
|
MyMutex::MyLock lock(parent->minit); // Also used in improccoord
|
||||||
|
|
||||||
int tr = TR_NONE;
|
int tr = TR_NONE;
|
||||||
if (params.coarse.rotate==90) tr |= TR_R90;
|
if (params.coarse.rotate==90) tr |= TR_R90;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "image16.h"
|
#include "image16.h"
|
||||||
#include "imagesource.h"
|
#include "imagesource.h"
|
||||||
#include "procevents.h"
|
#include "procevents.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
@ -52,11 +53,10 @@ class Crop : public DetailedCrop {
|
|||||||
int rqcropx, rqcropy, rqcropw, rqcroph; // size of the requested detail crop image (the image might be smaller) (without border)
|
int rqcropx, rqcropy, rqcropw, rqcroph; // size of the requested detail crop image (the image might be smaller) (without border)
|
||||||
int borderRequested, upperBorder, leftBorder;
|
int borderRequested, upperBorder, leftBorder;
|
||||||
|
|
||||||
|
|
||||||
bool cropAllocated;
|
bool cropAllocated;
|
||||||
DetailedCropListener* cropImageListener;
|
DetailedCropListener* cropImageListener;
|
||||||
|
|
||||||
Glib::Mutex cropMutex;
|
MyMutex cropMutex;
|
||||||
ImProcCoordinator* parent;
|
ImProcCoordinator* parent;
|
||||||
|
|
||||||
bool setCropSizes (int cx, int cy, int cw, int ch, int skip, bool internal);
|
bool setCropSizes (int cx, int cy, int cw, int ch, int skip, bool internal);
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "iccstore.h"
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "iccstore.h"
|
||||||
#include "iccmatrices.h"
|
#include "iccmatrices.h"
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include "safegtk.h"
|
#include "safegtk.h"
|
||||||
@ -62,7 +62,7 @@ std::vector<std::string> getWorkingProfiles () {
|
|||||||
|
|
||||||
std::vector<std::string> ICCStore::getOutputProfiles () {
|
std::vector<std::string> ICCStore::getOutputProfiles () {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
for (std::map<std::string, cmsHPROFILE>::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++){
|
for (std::map<std::string, cmsHPROFILE>::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++){
|
||||||
@ -83,8 +83,8 @@ ICCStore::getInstance(void)
|
|||||||
static ICCStore* instance_ = 0;
|
static ICCStore* instance_ = 0;
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
instance_ = new ICCStore();
|
instance_ = new ICCStore();
|
||||||
@ -153,7 +153,7 @@ cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) {
|
|||||||
|
|
||||||
cmsHPROFILE ICCStore::getProfile (Glib::ustring name) {
|
cmsHPROFILE ICCStore::getProfile (Glib::ustring name) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
std::map<std::string, cmsHPROFILE>::iterator r = fileProfiles.find (name);
|
std::map<std::string, cmsHPROFILE>::iterator r = fileProfiles.find (name);
|
||||||
if (r!=fileProfiles.end())
|
if (r!=fileProfiles.end())
|
||||||
@ -176,7 +176,7 @@ cmsHPROFILE ICCStore::getProfile (Glib::ustring name) {
|
|||||||
|
|
||||||
cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) {
|
cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
|
|
||||||
std::map<std::string, cmsHPROFILE>::iterator r = fileStdProfiles.find (name.uppercase());
|
std::map<std::string, cmsHPROFILE>::iterator r = fileStdProfiles.find (name.uppercase());
|
||||||
@ -187,7 +187,7 @@ cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) {
|
|||||||
|
|
||||||
ProfileContent ICCStore::getContent (Glib::ustring name) {
|
ProfileContent ICCStore::getContent (Glib::ustring name) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
return fileProfileContents[name];
|
return fileProfileContents[name];
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ ProfileContent ICCStore::getContent (Glib::ustring name) {
|
|||||||
// Reads all profiles from the given profiles dir
|
// Reads all profiles from the given profiles dir
|
||||||
void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) {
|
void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
//
|
//
|
||||||
fileProfiles.clear();
|
fileProfiles.clear();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class ICCStore {
|
|||||||
cmsHPROFILE xyz;
|
cmsHPROFILE xyz;
|
||||||
cmsHPROFILE srgb;
|
cmsHPROFILE srgb;
|
||||||
|
|
||||||
Glib::Mutex mutex_;
|
MyMutex mutex_;
|
||||||
|
|
||||||
ICCStore ();
|
ICCStore ();
|
||||||
void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map<std::string, cmsHPROFILE>& resultProfiles, std::map<std::string, ProfileContent> &resultProfileContents);
|
void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map<std::string, cmsHPROFILE>& resultProfiles, std::map<std::string, ProfileContent> &resultProfileContents);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "alignedbuffer.h"
|
#include "alignedbuffer.h"
|
||||||
#include "imagedimensions.h"
|
#include "imagedimensions.h"
|
||||||
@ -1021,7 +1022,7 @@ namespace rtengine {
|
|||||||
virtual ~IImage() {}
|
virtual ~IImage() {}
|
||||||
/** Returns a mutex that can is useful in many situations. No image operations shuold be performed without locking this mutex.
|
/** Returns a mutex that can is useful in many situations. No image operations shuold be performed without locking this mutex.
|
||||||
* @return The mutex */
|
* @return The mutex */
|
||||||
virtual Glib::Mutex& getMutex ()=0;
|
virtual MyMutex& getMutex ()=0;
|
||||||
virtual cmsHPROFILE getProfile ()=0;
|
virtual cmsHPROFILE getProfile ()=0;
|
||||||
/** Returns the bits per pixel of the image.
|
/** Returns the bits per pixel of the image.
|
||||||
* @return The bits per pixel of the image */
|
* @return The bits per pixel of the image */
|
||||||
|
@ -51,7 +51,7 @@ class Image16 : public IImage16, public ImageIO {
|
|||||||
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
||||||
|
|
||||||
// functions inherited from IImage16:
|
// functions inherited from IImage16:
|
||||||
virtual Glib::Mutex& getMutex () { return mutex (); }
|
virtual MyMutex& getMutex () { return mutex (); }
|
||||||
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
||||||
virtual int getBitsPerPixel () { return 8*sizeof(unsigned short); }
|
virtual int getBitsPerPixel () { return 8*sizeof(unsigned short); }
|
||||||
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
||||||
|
@ -46,7 +46,7 @@ class Image8 : public IImage8, public ImageIO {
|
|||||||
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
||||||
|
|
||||||
// functions inherited from IImage*:
|
// functions inherited from IImage*:
|
||||||
virtual Glib::Mutex& getMutex () { return mutex (); }
|
virtual MyMutex& getMutex () { return mutex (); }
|
||||||
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
||||||
virtual int getBitsPerPixel () { return 8*sizeof(unsigned char); }
|
virtual int getBitsPerPixel () { return 8*sizeof(unsigned char); }
|
||||||
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
||||||
|
@ -55,7 +55,7 @@ class Imagefloat : public IImagefloat, public ImageIO {
|
|||||||
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL);
|
||||||
|
|
||||||
// functions inherited from IImagefloat:
|
// functions inherited from IImagefloat:
|
||||||
virtual Glib::Mutex& getMutex () { return mutex (); }
|
virtual MyMutex& getMutex () { return mutex (); }
|
||||||
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
|
||||||
virtual int getBitsPerPixel () { return 8*sizeof(float); }
|
virtual int getBitsPerPixel () { return 8*sizeof(float); }
|
||||||
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
virtual int saveToFile (Glib::ustring fname) { return save (fname); }
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "../rtexif/rtexif.h"
|
#include "../rtexif/rtexif.h"
|
||||||
#include "imagedimensions.h"
|
#include "imagedimensions.h"
|
||||||
#include "iimage.h"
|
#include "iimage.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ class ImageIO : virtual public ImageDatas {
|
|||||||
procparams::ExifPairs exifChange;
|
procparams::ExifPairs exifChange;
|
||||||
IptcData* iptc;
|
IptcData* iptc;
|
||||||
const rtexif::TagDirectory* exifRoot;
|
const rtexif::TagDirectory* exifRoot;
|
||||||
Glib::Mutex imutex;
|
MyMutex imutex;
|
||||||
IIOSampleFormat sampleFormat;
|
IIOSampleFormat sampleFormat;
|
||||||
IIOSampleArrangement sampleArrangement;
|
IIOSampleArrangement sampleArrangement;
|
||||||
|
|
||||||
@ -122,7 +123,7 @@ class ImageIO : virtual public ImageDatas {
|
|||||||
void setMetadata (const rtexif::TagDirectory* eroot);
|
void setMetadata (const rtexif::TagDirectory* eroot);
|
||||||
void setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc);
|
void setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc);
|
||||||
void setOutputProfile (char* pdata, int plen);
|
void setOutputProfile (char* pdata, int plen);
|
||||||
Glib::Mutex& mutex () { return imutex; }
|
MyMutex& mutex () { return imutex; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
|||||||
|
|
||||||
|
|
||||||
if (todo & (M_INIT|M_LINDENOISE)) {
|
if (todo & (M_INIT|M_LINDENOISE)) {
|
||||||
Glib::Mutex::Lock lock(minit); // Also used in crop window
|
MyMutex::MyLock lock(minit); // Also used in crop window
|
||||||
|
|
||||||
imgsrc->HLRecovery_Global( params.hlrecovery ); // this handles Color HLRecovery
|
imgsrc->HLRecovery_Global( params.hlrecovery ); // this handles Color HLRecovery
|
||||||
|
|
||||||
@ -623,7 +623,7 @@ bool ImProcCoordinator::getAutoWB (double& temp, double& green, double equal) {
|
|||||||
|
|
||||||
if (imgsrc) {
|
if (imgsrc) {
|
||||||
if (lastAwbEqual != equal) {
|
if (lastAwbEqual != equal) {
|
||||||
Glib::Mutex::Lock lock(minit); // Also used in crop window
|
MyMutex::MyLock lock(minit); // Also used in crop window
|
||||||
double rm, gm, bm;
|
double rm, gm, bm;
|
||||||
imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
imgsrc->getAutoWBMultipliers(rm, gm, bm);
|
||||||
if (rm != -1) {
|
if (rm != -1) {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "procevents.h"
|
#include "procevents.h"
|
||||||
#include "dcrop.h"
|
#include "dcrop.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
|||||||
|
|
||||||
bool resultValid;
|
bool resultValid;
|
||||||
|
|
||||||
Glib::Mutex minit;
|
MyMutex minit;
|
||||||
|
|
||||||
void progress (Glib::ustring str, int pr);
|
void progress (Glib::ustring str, int pr);
|
||||||
void reallocAll ();
|
void reallocAll ();
|
||||||
@ -131,13 +132,13 @@ class ImProcCoordinator : public StagedImageProcessor {
|
|||||||
void setScale (int prevscale);
|
void setScale (int prevscale);
|
||||||
void updatePreviewImage (int todo, Crop* cropCall= NULL);
|
void updatePreviewImage (int todo, Crop* cropCall= NULL);
|
||||||
|
|
||||||
Glib::Mutex mProcessing;
|
MyMutex mProcessing;
|
||||||
ProcParams params;
|
ProcParams params;
|
||||||
|
|
||||||
// members of the updater:
|
// members of the updater:
|
||||||
Glib::Thread* thread;
|
Glib::Thread* thread;
|
||||||
Glib::Mutex updaterThreadStart;
|
MyMutex updaterThreadStart;
|
||||||
Glib::Mutex paramsUpdateMutex;
|
MyMutex paramsUpdateMutex;
|
||||||
int changeSinceLast;
|
int changeSinceLast;
|
||||||
bool updaterRunning;
|
bool updaterRunning;
|
||||||
ProcParams nextParams;
|
ProcParams nextParams;
|
||||||
|
@ -25,12 +25,13 @@
|
|||||||
#include "ffmanager.h"
|
#include "ffmanager.h"
|
||||||
#include "rtthumbnail.h"
|
#include "rtthumbnail.h"
|
||||||
#include "../rtgui/profilestore.h"
|
#include "../rtgui/profilestore.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
const Settings* settings;
|
const Settings* settings;
|
||||||
|
|
||||||
Glib::Mutex* lcmsMutex = NULL;
|
MyMutex* lcmsMutex = NULL;
|
||||||
|
|
||||||
int init (const Settings* s, Glib::ustring baseDir) {
|
int init (const Settings* s, Glib::ustring baseDir) {
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ int init (const Settings* s, Glib::ustring baseDir) {
|
|||||||
ImProcFunctions::initCache ();
|
ImProcFunctions::initCache ();
|
||||||
Thumbnail::initGamma ();
|
Thumbnail::initGamma ();
|
||||||
delete lcmsMutex;
|
delete lcmsMutex;
|
||||||
lcmsMutex = new Glib::Mutex;
|
lcmsMutex = new MyMutex;
|
||||||
dfm.init( s->darkFramesPath );
|
dfm.init( s->darkFramesPath );
|
||||||
ffm.init( s->flatFieldsPath );
|
ffm.init( s->flatFieldsPath );
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -629,8 +629,8 @@ LCPStore* LCPStore::getInstance()
|
|||||||
static LCPStore* instance_ = 0;
|
static LCPStore* instance_ = 0;
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
instance_ = new LCPStore();
|
instance_ = new LCPStore();
|
||||||
@ -642,7 +642,7 @@ LCPStore* LCPStore::getInstance()
|
|||||||
LCPProfile* LCPStore::getProfile (Glib::ustring filename) {
|
LCPProfile* LCPStore::getProfile (Glib::ustring filename) {
|
||||||
if (filename.length()==0 || !isValidLCPFileName(filename)) return NULL;
|
if (filename.length()==0 || !isValidLCPFileName(filename)) return NULL;
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
std::map<Glib::ustring, LCPProfile*>::iterator r = profileCache.find (filename);
|
std::map<Glib::ustring, LCPProfile*>::iterator r = profileCache.find (filename);
|
||||||
if (r!=profileCache.end()) return r->second;
|
if (r!=profileCache.end()) return r->second;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define _LCP_
|
#define _LCP_
|
||||||
|
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -92,7 +93,7 @@ namespace rtengine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class LCPStore {
|
class LCPStore {
|
||||||
Glib::Mutex mtx;
|
MyMutex mtx;
|
||||||
|
|
||||||
// Maps file name to profile as cache
|
// Maps file name to profile as cache
|
||||||
std::map<Glib::ustring, LCPProfile*> profileCache;
|
std::map<Glib::ustring, LCPProfile*> profileCache;
|
||||||
|
@ -205,7 +205,7 @@ void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &s
|
|||||||
|
|
||||||
void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw )
|
void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw )
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(getImageMutex);
|
MyMutex::MyLock lock(getImageMutex);
|
||||||
|
|
||||||
tran = defTransform (tran);
|
tran = defTransform (tran);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "iimage.h"
|
#include "iimage.h"
|
||||||
#include "../rtgui/cacheimagedata.h"
|
#include "../rtgui/cacheimagedata.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
#define HR_SCALE 2
|
#define HR_SCALE 2
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ class RawImageSource : public ImageSource {
|
|||||||
static void colorSpaceConversion (Imagefloat* im, ColorManagementParams &cmp, float rawWhitePoint, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName);
|
static void colorSpaceConversion (Imagefloat* im, ColorManagementParams &cmp, float rawWhitePoint, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Glib::Mutex getImageMutex; // locks getImage
|
MyMutex getImageMutex; // locks getImage
|
||||||
|
|
||||||
int W, H;
|
int W, H;
|
||||||
ColorTemp wb;
|
ColorTemp wb;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "rawmetadatalocation.h"
|
#include "rawmetadatalocation.h"
|
||||||
#include "iimage.h"
|
#include "iimage.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "LUT.h"
|
#include "LUT.h"
|
||||||
/**
|
/**
|
||||||
@ -417,7 +418,7 @@ namespace rtengine {
|
|||||||
void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData);
|
void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData);
|
||||||
|
|
||||||
|
|
||||||
extern Glib::Mutex* lcmsMutex;
|
extern MyMutex* lcmsMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "rtengine.h"
|
#include "rtengine.h"
|
||||||
#include "rtthumbnail.h"
|
#include "rtthumbnail.h"
|
||||||
|
#include "../rtgui/options.h"
|
||||||
#include "image8.h"
|
#include "image8.h"
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
#include "curves.h"
|
#include "curves.h"
|
||||||
@ -38,6 +39,8 @@
|
|||||||
#include "jpeg.h"
|
#include "jpeg.h"
|
||||||
#include "../rtgui/ppversion.h"
|
#include "../rtgui/ppversion.h"
|
||||||
|
|
||||||
|
extern Options options;
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq) {
|
Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq) {
|
||||||
@ -1280,7 +1283,7 @@ bool Thumbnail::readData (const Glib::ustring& fname) {
|
|||||||
SafeKeyFile keyFile;
|
SafeKeyFile keyFile;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Glib::Mutex::Lock thmbLock(thumbMutex);
|
MyMutex::MyLock thmbLock(thumbMutex);
|
||||||
if (!keyFile.load_from_file (fname))
|
if (!keyFile.load_from_file (fname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1309,7 +1312,14 @@ bool Thumbnail::readData (const Glib::ustring& fname) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Glib::Error &err) {}
|
catch (Glib::Error &err) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Thumbnail::readData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Thumbnail::readData / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1318,12 +1328,20 @@ bool Thumbnail::writeData (const Glib::ustring& fname) {
|
|||||||
|
|
||||||
SafeKeyFile keyFile;
|
SafeKeyFile keyFile;
|
||||||
|
|
||||||
Glib::Mutex::Lock thmbLock(thumbMutex);
|
MyMutex::MyLock thmbLock(thumbMutex);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if( safe_file_test(fname,Glib::FILE_TEST_EXISTS) )
|
if( safe_file_test(fname,Glib::FILE_TEST_EXISTS) )
|
||||||
keyFile.load_from_file (fname);
|
keyFile.load_from_file (fname);
|
||||||
} catch (...) {}
|
}
|
||||||
|
catch (Glib::Error &err) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Thumbnail::writeData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Thumbnail::writeData / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
|
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
|
||||||
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
|
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
|
||||||
@ -1343,8 +1361,11 @@ bool Thumbnail::writeData (const Glib::ustring& fname) {
|
|||||||
keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm);
|
keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm);
|
||||||
|
|
||||||
FILE *f = safe_g_fopen (fname, "wt");
|
FILE *f = safe_g_fopen (fname, "wt");
|
||||||
if (!f)
|
if (!f) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Thumbnail::writeData / Error: unable to open file \"\" with write access!\n", fname.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fprintf (f, "%s", keyFile.to_data().c_str());
|
fprintf (f, "%s", keyFile.to_data().c_str());
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
@ -26,12 +26,13 @@
|
|||||||
#include "image8.h"
|
#include "image8.h"
|
||||||
#include "image16.h"
|
#include "image16.h"
|
||||||
#include "imagefloat.h"
|
#include "imagefloat.h"
|
||||||
|
#include "../rtgui/threadutils.h"
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
|
|
||||||
class Thumbnail {
|
class Thumbnail {
|
||||||
|
|
||||||
Glib::Mutex thumbMutex;
|
MyMutex thumbMutex;
|
||||||
|
|
||||||
cmsHPROFILE camProfile;
|
cmsHPROFILE camProfile;
|
||||||
double iColorMatrix[3][3];
|
double iColorMatrix[3][3];
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define _BATCHQUEUE_
|
#define _BATCHQUEUE_
|
||||||
|
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
|
#include "threadutils.h"
|
||||||
#include "batchqueueentry.h"
|
#include "batchqueueentry.h"
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "../rtengine/safegtk.h"
|
#include "../rtengine/safegtk.h"
|
||||||
#include "multilangmgr.h"
|
#include "multilangmgr.h"
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQ
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!qMutex)
|
if (!qMutex)
|
||||||
qMutex = new Glib::Mutex ();
|
qMutex = new MyMutex ();
|
||||||
|
|
||||||
qMutex->lock ();
|
qMutex->lock ();
|
||||||
// look up if an older version is in the queue
|
// look up if an older version is in the queue
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "thumbnail.h"
|
#include "thumbnail.h"
|
||||||
|
|
||||||
class BQEntryUpdateListener {
|
class BQEntryUpdateListener {
|
||||||
@ -45,7 +46,7 @@ class BatchQueueEntryUpdater {
|
|||||||
bool stopped;
|
bool stopped;
|
||||||
std::list<Job> jqueue;
|
std::list<Job> jqueue;
|
||||||
Glib::Thread* thread;
|
Glib::Thread* thread;
|
||||||
Glib::Mutex* qMutex;
|
MyMutex* qMutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BatchQueueEntryUpdater ();
|
BatchQueueEntryUpdater ();
|
||||||
|
@ -36,13 +36,7 @@ int CacheImageData::load (const Glib::ustring& fname) {
|
|||||||
rtengine::SafeKeyFile keyFile;
|
rtengine::SafeKeyFile keyFile;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bool loaded = keyFile.load_from_file (fname);
|
if (keyFile.load_from_file (fname)) {
|
||||||
if (!loaded) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
printf("Failed to load_from_file(%s)\n", fname.c_str());
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyFile.has_group ("General")) {
|
if (keyFile.has_group ("General")) {
|
||||||
if (keyFile.has_key ("General", "MD5")) md5 = keyFile.get_string ("General", "MD5");
|
if (keyFile.has_key ("General", "MD5")) md5 = keyFile.get_string ("General", "MD5");
|
||||||
@ -101,8 +95,14 @@ int CacheImageData::load (const Glib::ustring& fname) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Glib::Error &err) {
|
catch (Glib::Error &err) {
|
||||||
printf("Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
if (options.rtSettings.verbose)
|
||||||
|
printf("CacheImageData::load / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("CacheImageData::load / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,19 @@ int CacheImageData::save (const Glib::ustring& fname) {
|
|||||||
|
|
||||||
rtengine::SafeKeyFile keyFile;
|
rtengine::SafeKeyFile keyFile;
|
||||||
|
|
||||||
if (safe_file_test(fname,Glib::FILE_TEST_EXISTS)) keyFile.load_from_file (fname);
|
if (safe_file_test(fname,Glib::FILE_TEST_EXISTS)) {
|
||||||
|
try {
|
||||||
|
keyFile.load_from_file (fname);
|
||||||
|
}
|
||||||
|
catch (Glib::Error &err) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("CacheImageData::save / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("CacheImageData::save / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keyFile.set_string ("General", "MD5", md5);
|
keyFile.set_string ("General", "MD5", md5);
|
||||||
keyFile.set_string ("General", "Version", VERSION); // Application's version
|
keyFile.set_string ("General", "Version", VERSION); // Application's version
|
||||||
@ -156,8 +168,11 @@ int CacheImageData::save (const Glib::ustring& fname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FILE *f = safe_g_fopen (fname, "wt");
|
FILE *f = safe_g_fopen (fname, "wt");
|
||||||
if (!f)
|
if (!f) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("CacheImageData::save / Error: unable to open file \"\" with write access!\n", fname.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fprintf (f, "%s", keyFile.to_data().c_str());
|
fprintf (f, "%s", keyFile.to_data().c_str());
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
@ -33,8 +33,8 @@ CacheManager::getInstance(void)
|
|||||||
static CacheManager* instance_ = 0;
|
static CacheManager* instance_ = 0;
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
instance_ = new CacheManager();
|
instance_ = new CacheManager();
|
||||||
@ -45,7 +45,7 @@ CacheManager::getInstance(void)
|
|||||||
|
|
||||||
void CacheManager::init () {
|
void CacheManager::init () {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
openEntries.clear ();
|
openEntries.clear ();
|
||||||
baseDir = options.cacheBaseDir;
|
baseDir = options.cacheBaseDir;
|
||||||
@ -75,7 +75,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname, const rtengine::p
|
|||||||
// take manager lock and search for entry, if found return it else release
|
// take manager lock and search for entry, if found return it else release
|
||||||
// lock and create it
|
// lock and create it
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
string_thumb_map::iterator r = openEntries.find (fname);
|
string_thumb_map::iterator r = openEntries.find (fname);
|
||||||
// if it is open, return it
|
// if it is open, return it
|
||||||
@ -119,7 +119,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname, const rtengine::p
|
|||||||
// was use it over our version. if not added we create the cache entry
|
// was use it over our version. if not added we create the cache entry
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
string_thumb_map::iterator r = openEntries.find (fname);
|
string_thumb_map::iterator r = openEntries.find (fname);
|
||||||
if (r!=openEntries.end()) {
|
if (r!=openEntries.end()) {
|
||||||
@ -138,7 +138,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname, const rtengine::p
|
|||||||
|
|
||||||
void CacheManager::deleteEntry (const Glib::ustring& fname) {
|
void CacheManager::deleteEntry (const Glib::ustring& fname) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
// check if it is opened
|
// check if it is opened
|
||||||
string_thumb_map::iterator r = openEntries.find (fname);
|
string_thumb_map::iterator r = openEntries.find (fname);
|
||||||
@ -200,7 +200,7 @@ void CacheManager::clearFromCache (const Glib::ustring& fname, bool leavenotrace
|
|||||||
|
|
||||||
void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) {
|
void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
std::string newmd5 = getMD5 (newfilename);
|
std::string newmd5 = getMD5 (newfilename);
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ void CacheManager::renameEntry (const std::string& oldfilename, const std::strin
|
|||||||
|
|
||||||
void CacheManager::closeThumbnail (Thumbnail* t) {
|
void CacheManager::closeThumbnail (Thumbnail* t) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
t->updateCache ();
|
t->updateCache ();
|
||||||
string_thumb_map::iterator r = openEntries.find (t->getFileName());
|
string_thumb_map::iterator r = openEntries.find (t->getFileName());
|
||||||
@ -239,14 +239,14 @@ void CacheManager::closeThumbnail (Thumbnail* t) {
|
|||||||
|
|
||||||
void CacheManager::closeCache () {
|
void CacheManager::closeCache () {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
applyCacheSizeLimitation ();
|
applyCacheSizeLimitation ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheManager::clearAll () {
|
void CacheManager::clearAll () {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
deleteDir ("images");
|
deleteDir ("images");
|
||||||
deleteDir ("aehistograms");
|
deleteDir ("aehistograms");
|
||||||
@ -264,7 +264,7 @@ void CacheManager::clearAll () {
|
|||||||
}
|
}
|
||||||
void CacheManager::clearThumbImages () {
|
void CacheManager::clearThumbImages () {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
deleteDir ("images");
|
deleteDir ("images");
|
||||||
deleteDir ("aehistograms");
|
deleteDir ("aehistograms");
|
||||||
@ -272,7 +272,7 @@ void CacheManager::clearThumbImages () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CacheManager::clearProfiles () {
|
void CacheManager::clearProfiles () {
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
deleteDir ("profiles");
|
deleteDir ("profiles");
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "thumbnail.h"
|
#include "thumbnail.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "../rtengine/procparams.h"
|
#include "../rtengine/procparams.h"
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
class Thumbnail;
|
class Thumbnail;
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ class CacheManager {
|
|||||||
|
|
||||||
string_thumb_map openEntries;
|
string_thumb_map openEntries;
|
||||||
Glib::ustring baseDir;
|
Glib::ustring baseDir;
|
||||||
Glib::Mutex mutex_;
|
MyMutex mutex_;
|
||||||
|
|
||||||
void deleteDir (const Glib::ustring& dirName);
|
void deleteDir (const Glib::ustring& dirName);
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ class CacheManager {
|
|||||||
|
|
||||||
void closeThumbnail (Thumbnail* t);
|
void closeThumbnail (Thumbnail* t);
|
||||||
|
|
||||||
const Glib::ustring& getBaseDir () { Glib::Mutex::Lock lock(mutex_); return baseDir; }
|
const Glib::ustring& getBaseDir () { MyMutex::MyLock lock(mutex_); return baseDir; }
|
||||||
void closeCache ();
|
void closeCache ();
|
||||||
|
|
||||||
static std::string getMD5 (const Glib::ustring& fname);
|
static std::string getMD5 (const Glib::ustring& fname);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define __CROPHANDLER__
|
#define __CROPHANDLER__
|
||||||
|
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
|
|
||||||
class CropHandlerListener {
|
class CropHandlerListener {
|
||||||
@ -71,7 +72,7 @@ class CropHandler : public rtengine::DetailedCropListener, public rtengine::Size
|
|||||||
Glib::RefPtr<Gdk::Pixbuf> cropPixbuf;
|
Glib::RefPtr<Gdk::Pixbuf> cropPixbuf;
|
||||||
Glib::RefPtr<Gdk::Pixbuf> cropPixbuftrue;
|
Glib::RefPtr<Gdk::Pixbuf> cropPixbuftrue;
|
||||||
|
|
||||||
Glib::Mutex cimg;
|
MyMutex cimg;
|
||||||
|
|
||||||
CropHandler ();
|
CropHandler ();
|
||||||
~CropHandler ();
|
~CropHandler ();
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "cropwindow.h"
|
#include "cropwindow.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "../rtengine/mytime.h"
|
#include "../rtengine/mytime.h"
|
||||||
#include "imagearea.h"
|
#include "imagearea.h"
|
||||||
#include "cursormanager.h"
|
#include "cursormanager.h"
|
||||||
@ -488,7 +489,7 @@ void CropWindow::pointerMoved (int x, int y) {
|
|||||||
if (pmhlistener) pmhlistener->pointerMoved (false, cropHandler.colorParams.working, mx, my, -1, -1, -1);
|
if (pmhlistener) pmhlistener->pointerMoved (false, cropHandler.colorParams.working, mx, my, -1, -1, -1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/*Glib::Mutex::Lock lock(cropHandler.cimg);
|
/*MyMutex::MyLock lock(cropHandler.cimg);
|
||||||
|
|
||||||
int vx = x - xpos - imgX;
|
int vx = x - xpos - imgX;
|
||||||
int vy = y - ypos - imgY;
|
int vy = y - ypos - imgY;
|
||||||
@ -630,7 +631,7 @@ void CropWindow::updateCursor (int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr) {
|
||||||
Glib::Mutex::Lock lock(cropHandler.cimg);
|
MyMutex::MyLock lock(cropHandler.cimg);
|
||||||
|
|
||||||
//MyTime t1, t2, t3, t4;
|
//MyTime t1, t2, t3, t4;
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "rtwindow.h"
|
#include "rtwindow.h"
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include "rtimage.h"
|
#include "rtimage.h"
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
static EditWindow* editWnd = NULL;
|
static EditWindow* editWnd = NULL;
|
||||||
|
|
||||||
@ -36,8 +37,8 @@ EditWindow* EditWindow::getInstance(RTWindow* p)
|
|||||||
|
|
||||||
if ( editWnd == NULL )
|
if ( editWnd == NULL )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( editWnd == 0 )
|
if ( editWnd == 0 )
|
||||||
{
|
{
|
||||||
editWnd = new EditWindow(p);
|
editWnd = new EditWindow(p);
|
||||||
|
@ -68,8 +68,8 @@ ExtProgStore* ExtProgStore::getInstance()
|
|||||||
static ExtProgStore* instance_ = 0;
|
static ExtProgStore* instance_ = 0;
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
if ( instance_ == 0 )
|
if ( instance_ == 0 )
|
||||||
{
|
{
|
||||||
instance_ = new ExtProgStore();
|
instance_ = new ExtProgStore();
|
||||||
@ -84,7 +84,7 @@ ExtProgStore::~ExtProgStore() {
|
|||||||
|
|
||||||
// Reads all profiles from the given profiles dir
|
// Reads all profiles from the given profiles dir
|
||||||
void ExtProgStore::init () {
|
void ExtProgStore::init () {
|
||||||
Glib::Mutex::Lock lock(mtx);
|
MyMutex::MyLock lock(mtx);
|
||||||
|
|
||||||
lActions.clear();
|
lActions.clear();
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
class ExtProgAction {
|
class ExtProgAction {
|
||||||
public:
|
public:
|
||||||
@ -40,7 +41,7 @@ public:
|
|||||||
|
|
||||||
// Stores all external programs that could be called by the user
|
// Stores all external programs that could be called by the user
|
||||||
class ExtProgStore {
|
class ExtProgStore {
|
||||||
Glib::Mutex mtx; // covers actions
|
MyMutex mtx; // covers actions
|
||||||
|
|
||||||
bool SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess);
|
bool SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "../rtengine/dfmanager.h"
|
#include "../rtengine/dfmanager.h"
|
||||||
#include "../rtengine/ffmanager.h"
|
#include "../rtengine/ffmanager.h"
|
||||||
#include "rtimage.h"
|
#include "rtimage.h"
|
||||||
#include "guiutils.h"
|
#include "threadutils.h"
|
||||||
|
|
||||||
extern Options options;
|
extern Options options;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "cursormanager.h"
|
#include "cursormanager.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "../rtengine/safegtk.h"
|
#include "../rtengine/safegtk.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -463,7 +463,7 @@ void FileCatalog::closeDir () {
|
|||||||
fileNameList.clear ();
|
fileNameList.clear ();
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(dirEFSMutex);
|
MyMutex::MyLock lock(dirEFSMutex);
|
||||||
dirEFS.clear ();
|
dirEFS.clear ();
|
||||||
}
|
}
|
||||||
hasValidCurrentEFS = false;
|
hasValidCurrentEFS = false;
|
||||||
@ -588,7 +588,7 @@ void FileCatalog::previewReady (int dir_id, FileBrowserEntry* fdn) {
|
|||||||
const CacheImageData* cfs = fdn->thumbnail->getCacheImageData();
|
const CacheImageData* cfs = fdn->thumbnail->getCacheImageData();
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(dirEFSMutex);
|
MyMutex::MyLock lock(dirEFSMutex);
|
||||||
if (cfs->exifValid) {
|
if (cfs->exifValid) {
|
||||||
if (cfs->fnumber < dirEFS.fnumberFrom)
|
if (cfs->fnumber < dirEFS.fnumberFrom)
|
||||||
dirEFS.fnumberFrom = cfs->fnumber;
|
dirEFS.fnumberFrom = cfs->fnumber;
|
||||||
@ -634,7 +634,7 @@ void FileCatalog::previewsFinishedUI () {
|
|||||||
if (filterPanel) {
|
if (filterPanel) {
|
||||||
filterPanel->set_sensitive (true);
|
filterPanel->set_sensitive (true);
|
||||||
if ( !hasValidCurrentEFS ){
|
if ( !hasValidCurrentEFS ){
|
||||||
Glib::Mutex::Lock lock(dirEFSMutex);
|
MyMutex::MyLock lock(dirEFSMutex);
|
||||||
currentEFS = dirEFS;
|
currentEFS = dirEFS;
|
||||||
filterPanel->setFilter ( dirEFS,true );
|
filterPanel->setFilter ( dirEFS,true );
|
||||||
}else {
|
}else {
|
||||||
@ -672,7 +672,7 @@ void FileCatalog::previewsFinished (int dir_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!hasValidCurrentEFS) {
|
if (!hasValidCurrentEFS) {
|
||||||
Glib::Mutex::Lock lock(dirEFSMutex);
|
MyMutex::MyLock lock(dirEFSMutex);
|
||||||
currentEFS = dirEFS;
|
currentEFS = dirEFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,7 +1322,7 @@ BrowserFilter FileCatalog::getFilter () {
|
|||||||
filter.exifFilterEnabled = false;
|
filter.exifFilterEnabled = false;
|
||||||
else {
|
else {
|
||||||
if (!hasValidCurrentEFS) {
|
if (!hasValidCurrentEFS) {
|
||||||
Glib::Mutex::Lock lock(dirEFSMutex);
|
MyMutex::MyLock lock(dirEFSMutex);
|
||||||
filter.exifFilter = dirEFS;
|
filter.exifFilter = dirEFS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "exportpanel.h"
|
#include "exportpanel.h"
|
||||||
#include "previewloader.h"
|
#include "previewloader.h"
|
||||||
#include "multilangmgr.h"
|
#include "multilangmgr.h"
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
|
|
||||||
class DirEntry {
|
class DirEntry {
|
||||||
@ -133,7 +134,7 @@ class FileCatalog : public Gtk::VBox,
|
|||||||
Gtk::Button* zoomInButton;
|
Gtk::Button* zoomInButton;
|
||||||
Gtk::Button* zoomOutButton;
|
Gtk::Button* zoomOutButton;
|
||||||
|
|
||||||
Glib::Mutex dirEFSMutex;
|
MyMutex dirEFSMutex;
|
||||||
ExifFilterSettings dirEFS;
|
ExifFilterSettings dirEFS;
|
||||||
ExifFilterSettings currentEFS;
|
ExifFilterSettings currentEFS;
|
||||||
bool hasValidCurrentEFS;
|
bool hasValidCurrentEFS;
|
||||||
|
450
rtgui/guiutils.h
450
rtgui/guiutils.h
@ -20,7 +20,6 @@
|
|||||||
#define __GUI_UTILS_
|
#define __GUI_UTILS_
|
||||||
|
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include <glibmm.h>
|
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -77,455 +76,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
// We don't trace mutex
|
|
||||||
#undef TRACE_MYRWMUTEX
|
|
||||||
#define TRACE_MYRWMUTEX 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Uncomment this if you want to bypass the CMakeList options and force the values
|
|
||||||
// Of course, DO NOT COMMIT! :)
|
|
||||||
|
|
||||||
//#undef PROTECT_VECTORS
|
|
||||||
//#define PROTECT_VECTORS 1
|
|
||||||
//#undef TRACE_MYRWMUTEX
|
|
||||||
//#define TRACE_MYRWMUTEX 1
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Custom RWLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
|
||||||
*
|
|
||||||
* It may be slower, but thread safe!
|
|
||||||
*/
|
|
||||||
class MyRWMutex {
|
|
||||||
public:
|
|
||||||
Glib::Mutex handlerMutex;
|
|
||||||
Glib::Cond access;
|
|
||||||
size_t writerCount;
|
|
||||||
size_t readerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
Glib::ustring lastWriterFile;
|
|
||||||
int lastWriterLine;
|
|
||||||
// Unfortunately, ownerThread may not be the culprit of a deadlock, it can be another concurrent Reader...
|
|
||||||
void* ownerThread;
|
|
||||||
|
|
||||||
MyRWMutex() : writerCount(0), readerCount(0), lastWriterLine(0), ownerThread(NULL) {}
|
|
||||||
#else
|
|
||||||
MyRWMutex() : writerCount(0), readerCount(0) {}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Custom ReaderLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class MyReaderLock {
|
|
||||||
|
|
||||||
MyRWMutex& rwMutex;
|
|
||||||
bool locked;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
static unsigned int readerLockCounter;
|
|
||||||
int locknumber;
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline MyReaderLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0)
|
|
||||||
#else
|
|
||||||
public:
|
|
||||||
inline MyReaderLock(MyRWMutex& mutex) : rwMutex(mutex)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
locknumber = readerLockCounter++;
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.writerCount) {
|
|
||||||
// There's no writer operating, we can increment the writer count which will lock writers
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " ++ new owner";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The writer count is non null, but we can be the owner of the writer lock
|
|
||||||
// It will be the case if the reader count is non null too.
|
|
||||||
if (!rwMutex.readerCount) {
|
|
||||||
// the mutex is in real write mode, we're waiting to see it null
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
|
||||||
#endif
|
|
||||||
while (rwMutex.writerCount)
|
|
||||||
rwMutex.access.wait(rwMutex.handlerMutex);
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = file;
|
|
||||||
rwMutex.lastWriterLine = line;
|
|
||||||
rwMutex.ownerThread = thread;
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R ++ new owner";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// then we can increment the reader count
|
|
||||||
++rwMutex.readerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
|
||||||
inline void acquire(const char* file, const int line)
|
|
||||||
#else
|
|
||||||
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
|
||||||
inline void acquire()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (!locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock)";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.writerCount) {
|
|
||||||
// There's no writer operating, we can increment the writer count which will lock writers
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " ++ new owner";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The writer count is non null, but a reader can be the owner of the writer lock,
|
|
||||||
// it will be the case if the reader count is non null too.
|
|
||||||
if (!rwMutex.readerCount) {
|
|
||||||
// the mutex is in real write mode, we're waiting to see it null
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
|
||||||
#endif
|
|
||||||
while (rwMutex.writerCount)
|
|
||||||
rwMutex.access.wait(rwMutex.handlerMutex);
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = file;
|
|
||||||
rwMutex.lastWriterLine = line;
|
|
||||||
rwMutex.ownerThread = thread;
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock) ++ new owner";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// then we can increment the reader count
|
|
||||||
++rwMutex.readerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already locked by this object - R (lock)" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
inline ~MyReaderLock() {
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
// decrement the writer number first
|
|
||||||
--rwMutex.readerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << " / unlocking - R - ReaderCount: " << rwMutex.readerCount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.readerCount) {
|
|
||||||
// no more reader, so we decrement the writer count
|
|
||||||
--rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = "";
|
|
||||||
rwMutex.lastWriterLine = 0;
|
|
||||||
rwMutex.ownerThread = NULL;
|
|
||||||
std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount;
|
|
||||||
#endif
|
|
||||||
// and signal the next waiting reader/writer that it's free
|
|
||||||
rwMutex.access.broadcast();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - R" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
|
||||||
inline void release(const char* file, const int line)
|
|
||||||
#else
|
|
||||||
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
|
||||||
inline void release()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
// decrement the writer number first
|
|
||||||
--rwMutex.readerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << " / unlocking - R (release) - ReaderCount: " << rwMutex.readerCount;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.readerCount) {
|
|
||||||
// no more reader, so we decrement the writer count
|
|
||||||
--rwMutex.writerCount;
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = "";
|
|
||||||
rwMutex.lastWriterLine = 0;
|
|
||||||
rwMutex.ownerThread = NULL;
|
|
||||||
std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount;
|
|
||||||
#endif
|
|
||||||
// and signal the next waiting reader/writer that it's free
|
|
||||||
rwMutex.access.broadcast();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = false;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already unlocked - R (release)" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Custom WriterLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class MyWriterLock {
|
|
||||||
|
|
||||||
MyRWMutex& rwMutex;
|
|
||||||
bool locked;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
static unsigned int writerLockCounter;
|
|
||||||
int locknumber;
|
|
||||||
public:
|
|
||||||
inline MyWriterLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0)
|
|
||||||
#else
|
|
||||||
public:
|
|
||||||
inline MyWriterLock(MyRWMutex& mutex) : rwMutex(mutex)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
locknumber = writerLockCounter++;
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - W";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (rwMutex.writerCount) {
|
|
||||||
// The writer count is non null, so we have to wait for it to be null again
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
|
||||||
#endif
|
|
||||||
while (rwMutex.writerCount)
|
|
||||||
rwMutex.access.wait(rwMutex.handlerMutex);
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// then we can increment the writer count
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = file;
|
|
||||||
rwMutex.lastWriterLine = line;
|
|
||||||
rwMutex.ownerThread = thread;
|
|
||||||
std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
|
||||||
inline void acquire(const char* file, const int line)
|
|
||||||
#else
|
|
||||||
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
|
||||||
inline void acquire()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (!locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (rwMutex.writerCount) {
|
|
||||||
// The writer count is non null, so we have to wait for it to be null again
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
|
||||||
#endif
|
|
||||||
while (rwMutex.writerCount)
|
|
||||||
rwMutex.access.wait(rwMutex.handlerMutex);
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// then we can increment the reader count
|
|
||||||
++rwMutex.writerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = file;
|
|
||||||
rwMutex.lastWriterLine = line;
|
|
||||||
rwMutex.ownerThread = thread;
|
|
||||||
std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already locked by this object - W (lock)" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
inline ~MyWriterLock() {
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
// decrement the writer number first
|
|
||||||
--rwMutex.writerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << " / unlocking - W";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.writerCount) {
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = "";
|
|
||||||
rwMutex.lastWriterLine = 0;
|
|
||||||
rwMutex.ownerThread = NULL;
|
|
||||||
std::cout << " -- new owner possible!";
|
|
||||||
#endif
|
|
||||||
// The writer count is null again, so we can wake up the next writer or reader
|
|
||||||
rwMutex.access.broadcast();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
|
||||||
inline void release(const char* file, const int line)
|
|
||||||
#else
|
|
||||||
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
|
||||||
inline void release()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
void* thread = Glib::Thread::self();
|
|
||||||
#endif
|
|
||||||
if (locked) {
|
|
||||||
// to operate safely
|
|
||||||
rwMutex.handlerMutex.lock();
|
|
||||||
|
|
||||||
// decrement the writer number first
|
|
||||||
--rwMutex.writerCount;
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << thread << "/" << locknumber << " / unlocking - W (release)";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!rwMutex.writerCount) {
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
rwMutex.lastWriterFile = "";
|
|
||||||
rwMutex.lastWriterLine = 0;
|
|
||||||
rwMutex.ownerThread = NULL;
|
|
||||||
std::cout << " -- new owner possible!";
|
|
||||||
#endif
|
|
||||||
// The writer count is null again, so we can wake up the next writer or reader
|
|
||||||
rwMutex.access.broadcast();
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rwMutex.handlerMutex.unlock();
|
|
||||||
|
|
||||||
locked = false;
|
|
||||||
}
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W (release)" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if TRACE_MYRWMUTEX
|
|
||||||
#define MYREADERLOCK(ln, e) MyReaderLock ln(e, #e, __FILE__, __LINE__);
|
|
||||||
#define MYWRITERLOCK(ln, e) MyWriterLock ln(e, #e, __FILE__, __LINE__);
|
|
||||||
#define MYREADERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__);
|
|
||||||
#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__);
|
|
||||||
#define MYREADERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__);
|
|
||||||
#define MYWRITERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__);
|
|
||||||
#else
|
|
||||||
#define MYREADERLOCK(ln, e) MyReaderLock ln(e);
|
|
||||||
#define MYWRITERLOCK(ln, e) MyWriterLock ln(e);
|
|
||||||
#define MYREADERLOCK_ACQUIRE(ln) ln.acquire();
|
|
||||||
#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire();
|
|
||||||
#define MYREADERLOCK_RELEASE(ln) ln.release();
|
|
||||||
#define MYWRITERLOCK_RELEASE(ln) ln.release();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief subclass of Gtk::ScrolledWindow in order to handle the scrollwheel
|
* @brief subclass of Gtk::ScrolledWindow in order to handle the scrollwheel
|
||||||
*/
|
*/
|
||||||
|
@ -90,6 +90,12 @@ int processLineParams( int argc, char **argv );
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
setlocale(LC_ALL,"");
|
setlocale(LC_ALL,"");
|
||||||
|
|
||||||
|
Glib::thread_init();
|
||||||
|
gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave)));
|
||||||
|
gdk_threads_init();
|
||||||
|
Gio::init ();
|
||||||
|
|
||||||
#ifdef BUILD_BUNDLE
|
#ifdef BUILD_BUNDLE
|
||||||
char exname[512] = {0};
|
char exname[512] = {0};
|
||||||
Glib::ustring exePath;
|
Glib::ustring exePath;
|
||||||
@ -127,11 +133,6 @@ int main(int argc, char **argv)
|
|||||||
licensePath = LICENCE_SEARCH_PATH;
|
licensePath = LICENCE_SEARCH_PATH;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Glib::thread_init();
|
|
||||||
gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave)));
|
|
||||||
gdk_threads_init();
|
|
||||||
Gio::init ();
|
|
||||||
|
|
||||||
mainThread = Glib::Thread::self();
|
mainThread = Glib::Thread::self();
|
||||||
|
|
||||||
Options::load ();
|
Options::load ();
|
||||||
|
@ -499,22 +499,20 @@ int Options::readFromFile (Glib::ustring fname) {
|
|||||||
|
|
||||||
rtengine::SafeKeyFile keyFile;
|
rtengine::SafeKeyFile keyFile;
|
||||||
|
|
||||||
try {
|
|
||||||
if( !safe_file_test(fname,Glib::FILE_TEST_EXISTS))
|
if( !safe_file_test(fname,Glib::FILE_TEST_EXISTS))
|
||||||
return 1;
|
return 1;
|
||||||
if (!keyFile.load_from_file (fname))
|
|
||||||
return 1;
|
try {
|
||||||
}
|
if (keyFile.load_from_file (fname)) {
|
||||||
catch (Glib::FileError &err) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaults ();
|
setDefaults ();
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
if (keyFile.has_group ("General")) {
|
if (keyFile.has_group ("General")) {
|
||||||
if (keyFile.has_key ("General", "TabbedEditor")) tabbedUI= keyFile.get_boolean ("General", "TabbedEditor");
|
if (keyFile.has_key ("General", "TabbedEditor")) tabbedUI= keyFile.get_boolean ("General", "TabbedEditor");
|
||||||
if (keyFile.has_key ("General", "StartupDirectory")){
|
if (keyFile.has_key ("General", "StartupDirectory")){
|
||||||
if( keyFile.get_string ("General", "StartupDirectory") == "home") startupDir = STARTUPDIR_HOME;
|
if ( keyFile.get_string ("General", "StartupDirectory") == "home") startupDir = STARTUPDIR_HOME;
|
||||||
else if ( keyFile.get_string ("General", "StartupDirectory") == "current") startupDir = STARTUPDIR_CURRENT;
|
else if ( keyFile.get_string ("General", "StartupDirectory") == "current") startupDir = STARTUPDIR_CURRENT;
|
||||||
else if ( keyFile.get_string ("General", "StartupDirectory") == "last") startupDir = STARTUPDIR_LAST;
|
else if ( keyFile.get_string ("General", "StartupDirectory") == "last") startupDir = STARTUPDIR_LAST;
|
||||||
else if ( keyFile.get_string ("General", "StartupDirectory") == "custom") startupDir = STARTUPDIR_CUSTOM;
|
else if ( keyFile.get_string ("General", "StartupDirectory") == "custom") startupDir = STARTUPDIR_CUSTOM;
|
||||||
@ -669,8 +667,6 @@ if (keyFile.has_group ("GUI")) {
|
|||||||
if (keyFile.has_key ("GUI", "UseIconNoText")) UseIconNoText = keyFile.get_boolean ("GUI", "UseIconNoText");
|
if (keyFile.has_key ("GUI", "UseIconNoText")) UseIconNoText = keyFile.get_boolean ("GUI", "UseIconNoText");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (keyFile.has_group ("Crop Settings")) {
|
if (keyFile.has_group ("Crop Settings")) {
|
||||||
if (keyFile.has_key ("Crop Settings", "PPI")) cropPPI = keyFile.get_integer ("Crop Settings", "PPI");
|
if (keyFile.has_key ("Crop Settings", "PPI")) cropPPI = keyFile.get_integer ("Crop Settings", "PPI");
|
||||||
}
|
}
|
||||||
@ -764,9 +760,25 @@ if (keyFile.has_group ("Dialogs")) {
|
|||||||
safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
|
safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
filterOutParsedExtensions ();
|
filterOutParsedExtensions ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Glib::Error &err) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Options::safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section,
|
bool Options::safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section,
|
||||||
@ -1015,8 +1027,11 @@ int Options::saveToFile (Glib::ustring fname) {
|
|||||||
keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
|
keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
|
||||||
|
|
||||||
FILE *f = safe_g_fopen (fname, "wt");
|
FILE *f = safe_g_fopen (fname, "wt");
|
||||||
if (f==NULL)
|
if (f==NULL) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("Options::saveToFile / Error: unable to open file \"\" with write access!\n", fname.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fprintf (f, "%s", keyFile.to_data().c_str());
|
fprintf (f, "%s", keyFile.to_data().c_str());
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
@ -172,7 +172,7 @@ void PreviewHandler::imageReady (CropParams cp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) {
|
Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) {
|
||||||
Glib::Mutex::Lock lock(previewImgMutex);
|
MyMutex::MyLock lock(previewImgMutex);
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
|
Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) {
|
Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) {
|
||||||
Glib::Mutex::Lock lock(previewImgMutex);
|
MyMutex::MyLock lock(previewImgMutex);
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
|
Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define _PREVIEWHANDLER_
|
#define _PREVIEWHANDLER_
|
||||||
|
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
@ -49,10 +50,9 @@ class PreviewHandler : public rtengine::PreviewImageListener {
|
|||||||
double previewScale;
|
double previewScale;
|
||||||
PreviewHandlerIdleHelper* pih;
|
PreviewHandlerIdleHelper* pih;
|
||||||
std::list<PreviewListener*> listeners;
|
std::list<PreviewListener*> listeners;
|
||||||
Glib::Mutex previewImgMutex;
|
MyMutex previewImgMutex;
|
||||||
Glib::RefPtr<Gdk::Pixbuf> previewImg;
|
Glib::RefPtr<Gdk::Pixbuf> previewImg;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PreviewHandler ();
|
PreviewHandler ();
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include "previewloader.h"
|
#include "previewloader.h"
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "../rtengine/safegtk.h"
|
#include "../rtengine/safegtk.h"
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -75,7 +76,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Glib::ThreadPool* threadPool_;
|
Glib::ThreadPool* threadPool_;
|
||||||
Glib::Mutex mutex_;
|
MyMutex mutex_;
|
||||||
JobSet jobs_;
|
JobSet jobs_;
|
||||||
gint nConcurrentThreads;
|
gint nConcurrentThreads;
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ public:
|
|||||||
{
|
{
|
||||||
Job j;
|
Job j;
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
MyMutex::MyLock lock(mutex_);
|
||||||
|
|
||||||
// nothing to do; could be jobs have been removed
|
// nothing to do; could be jobs have been removed
|
||||||
if ( jobs_.empty() )
|
if ( jobs_.empty() )
|
||||||
@ -137,8 +138,8 @@ PreviewLoader* PreviewLoader::getInstance(void)
|
|||||||
static PreviewLoader* instance_ = NULL;
|
static PreviewLoader* instance_ = NULL;
|
||||||
if ( instance_ == NULL )
|
if ( instance_ == NULL )
|
||||||
{
|
{
|
||||||
static Glib::Mutex smutex_;
|
static MyMutex smutex_;
|
||||||
Glib::Mutex::Lock lock(smutex_);
|
MyMutex::MyLock lock(smutex_);
|
||||||
|
|
||||||
if ( instance_ == NULL ) instance_ = new PreviewLoader();
|
if ( instance_ == NULL ) instance_ = new PreviewLoader();
|
||||||
}
|
}
|
||||||
@ -152,7 +153,7 @@ void PreviewLoader::add(int dir_id, const Glib::ustring& dir_entry, PreviewLoade
|
|||||||
if ( l != 0 )
|
if ( l != 0 )
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(impl_->mutex_);
|
MyMutex::MyLock lock(impl_->mutex_);
|
||||||
|
|
||||||
// create a new job and append to queue
|
// create a new job and append to queue
|
||||||
DEBUG("saving job %s",dir_entry.c_str());
|
DEBUG("saving job %s",dir_entry.c_str());
|
||||||
@ -168,7 +169,7 @@ void PreviewLoader::add(int dir_id, const Glib::ustring& dir_entry, PreviewLoade
|
|||||||
void PreviewLoader::removeAllJobs(void)
|
void PreviewLoader::removeAllJobs(void)
|
||||||
{
|
{
|
||||||
DEBUG("stop %d",impl_->nConcurrentThreads);
|
DEBUG("stop %d",impl_->nConcurrentThreads);
|
||||||
Glib::Mutex::Lock lock(impl_->mutex_);
|
MyMutex::MyLock lock(impl_->mutex_);
|
||||||
impl_->jobs_.clear();
|
impl_->jobs_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ bool ProfileStore::init () {
|
|||||||
return false;
|
return false;
|
||||||
if (storeState == STORESTATE_NOTINITIALIZED) {
|
if (storeState == STORESTATE_NOTINITIALIZED) {
|
||||||
storeState = STORESTATE_BEINGINITIALIZED;
|
storeState = STORESTATE_BEINGINITIALIZED;
|
||||||
parseMutex = new Glib::Mutex();
|
parseMutex = new MyMutex();
|
||||||
_parseProfiles ();
|
_parseProfiles ();
|
||||||
storeState = STORESTATE_INITIALIZED;
|
storeState = STORESTATE_INITIALIZED;
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ ProfileStore::~ProfileStore () {
|
|||||||
|
|
||||||
// This lock prevent object's suppression while scanning the directories
|
// This lock prevent object's suppression while scanning the directories
|
||||||
storeState = STORESTATE_DELETED;
|
storeState = STORESTATE_DELETED;
|
||||||
Glib::Mutex::Lock lock(*parseMutex);
|
MyMutex::MyLock lock(*parseMutex);
|
||||||
|
|
||||||
for (std::map<Glib::ustring,PartialProfile*>::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++) {
|
for (std::map<Glib::ustring,PartialProfile*>::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++) {
|
||||||
if (i->second->pparams) delete i->second->pparams;
|
if (i->second->pparams) delete i->second->pparams;
|
||||||
@ -71,7 +71,7 @@ void ProfileStore::parseProfiles () {
|
|||||||
if (!init())
|
if (!init())
|
||||||
// I don't even know if this situation can occur
|
// I don't even know if this situation can occur
|
||||||
return;
|
return;
|
||||||
Glib::Mutex::Lock lock(*parseMutex);
|
MyMutex::MyLock lock(*parseMutex);
|
||||||
|
|
||||||
_parseProfiles ();
|
_parseProfiles ();
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ const PartialProfile* ProfileStore::getProfile (const Glib::ustring& profname) {
|
|||||||
if (!init())
|
if (!init())
|
||||||
// I don't even know if this situation can occur
|
// I don't even know if this situation can occur
|
||||||
return NULL;
|
return NULL;
|
||||||
Glib::Mutex::Lock lock(*parseMutex);
|
MyMutex::MyLock lock(*parseMutex);
|
||||||
|
|
||||||
if (partProfiles.find(profname) != partProfiles.end()) {
|
if (partProfiles.find(profname) != partProfiles.end()) {
|
||||||
return partProfiles[profname];
|
return partProfiles[profname];
|
||||||
@ -165,7 +165,7 @@ std::vector<Glib::ustring> ProfileStore::getProfileNames () {
|
|||||||
if (!init())
|
if (!init())
|
||||||
// I don't even know if this situation can occur
|
// I don't even know if this situation can occur
|
||||||
return ret;
|
return ret;
|
||||||
Glib::Mutex::Lock lock(*parseMutex);
|
MyMutex::MyLock lock(*parseMutex);
|
||||||
|
|
||||||
for (std::map<Glib::ustring,PartialProfile*>::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++)
|
for (std::map<Glib::ustring,PartialProfile*>::iterator i = partProfiles.begin(); i!=partProfiles.end(); i++)
|
||||||
ret.push_back (i->first);
|
ret.push_back (i->first);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../rtengine/rtengine.h"
|
#include "../rtengine/rtengine.h"
|
||||||
|
#include "threadutils.h"
|
||||||
#include "paramsedited.h"
|
#include "paramsedited.h"
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ class ProfileStore {
|
|||||||
STORESTATE_DELETED
|
STORESTATE_DELETED
|
||||||
} StoreState;
|
} StoreState;
|
||||||
|
|
||||||
Glib::Mutex *parseMutex;
|
MyMutex *parseMutex;
|
||||||
StoreState storeState;
|
StoreState storeState;
|
||||||
std::map<Glib::ustring, rtengine::procparams::PartialProfile*> partProfiles;
|
std::map<Glib::ustring, rtengine::procparams::PartialProfile*> partProfiles;
|
||||||
void parseDir (const Glib::ustring& pdir);
|
void parseDir (const Glib::ustring& pdir);
|
||||||
|
@ -100,6 +100,7 @@ void RTImage::setPaths(Options &opt) {
|
|||||||
else {
|
else {
|
||||||
configFilename = Glib::build_filename(argv0, Glib::build_filename("themes", Glib::ustring::format(opt.theme, ".iconset")));
|
configFilename = Glib::build_filename(argv0, Glib::build_filename("themes", Glib::ustring::format(opt.theme, ".iconset")));
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
if (!safe_file_test(configFilename, Glib::FILE_TEST_EXISTS) || !keyFile.load_from_file (configFilename)) {
|
if (!safe_file_test(configFilename, Glib::FILE_TEST_EXISTS) || !keyFile.load_from_file (configFilename)) {
|
||||||
// ...otherwise fallback to the iconset set in default.iconset
|
// ...otherwise fallback to the iconset set in default.iconset
|
||||||
configFilename = Glib::build_filename(argv0, Glib::build_filename("themes", "Default.iconset"));
|
configFilename = Glib::build_filename(argv0, Glib::build_filename("themes", "Default.iconset"));
|
||||||
@ -107,6 +108,15 @@ void RTImage::setPaths(Options &opt) {
|
|||||||
hasKeyFile = false;
|
hasKeyFile = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Glib::Error &err) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("RTImage::setPaths / Error code %d while reading values from \"%s\":\n%s\n", err.code(), configFilename.c_str(), err.what().c_str());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
if (options.rtSettings.verbose)
|
||||||
|
printf("RTImage::setPaths / Unknown exception while trying to load \"%s\"!\n", configFilename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (hasKeyFile && keyFile.has_group ("General")) {
|
if (hasKeyFile && keyFile.has_group ("General")) {
|
||||||
Glib::ustring iSet;
|
Glib::ustring iSet;
|
||||||
|
619
rtgui/threadutils.h
Normal file
619
rtgui/threadutils.h
Normal file
@ -0,0 +1,619 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of RawTherapee.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
||||||
|
*
|
||||||
|
* RawTherapee is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RawTherapee is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _THREADUTILS_
|
||||||
|
#define _THREADUTILS_
|
||||||
|
|
||||||
|
#include <glibmm.h>
|
||||||
|
#include <csignal> // for raise()
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
// We don't trace mutex
|
||||||
|
#undef TRACE_MYRWMUTEX
|
||||||
|
#define TRACE_MYRWMUTEX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Uncomment this if you want to bypass the CMakeList options and force the values
|
||||||
|
// Of course, DO NOT COMMIT!
|
||||||
|
|
||||||
|
//#undef PROTECT_VECTORS
|
||||||
|
//#define PROTECT_VECTORS 1
|
||||||
|
//#undef TRACE_MYRWMUTEX
|
||||||
|
//#define TRACE_MYRWMUTEX 1
|
||||||
|
//#undef STRICT_MUTEX
|
||||||
|
//#define STRICT_MUTEX 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom Mutex to replace Glib::Threads::Mutex, which behave differently on windows (recursive) and linux (non-recursive), by a recursive and "debugable" one
|
||||||
|
*
|
||||||
|
* This implementation will behave like a Glib::Threads::RecMutex (STRICT_MUTEX=0) or a Glib::Threads::Mutex (STRICT_MUTEX=1), but in this case, the application will
|
||||||
|
* crash instead of freezing.
|
||||||
|
*
|
||||||
|
* In Debug builds, a printf will let you know that the MyMutex was already locked
|
||||||
|
*
|
||||||
|
* The default and recommended mode is STRICT_MUTEX=1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
class MyMutex : public Glib::RecMutex {
|
||||||
|
#else
|
||||||
|
class MyMutex : public Glib::Threads::RecMutex {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STRICT_MUTEX || !defined(NDEBUG)
|
||||||
|
private:
|
||||||
|
bool alreadyLocked;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
class MyLock;
|
||||||
|
|
||||||
|
#if STRICT_MUTEX || !defined(NDEBUG)
|
||||||
|
MyMutex() : alreadyLocked(false) {}
|
||||||
|
#else
|
||||||
|
MyMutex() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void lock() {
|
||||||
|
#ifdef WIN32
|
||||||
|
Glib::RecMutex::lock();
|
||||||
|
#else
|
||||||
|
Glib::Threads::RecMutex::lock();
|
||||||
|
#endif
|
||||||
|
#if STRICT_MUTEX || !defined(NDEBUG)
|
||||||
|
if (alreadyLocked) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
printf("Warning: MyMutex already locked!\n"); // breakpoint
|
||||||
|
#endif
|
||||||
|
#if STRICT_MUTEX
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#ifdef WIN32
|
||||||
|
DebugBreak();
|
||||||
|
#else
|
||||||
|
raise(SIGTRAP);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
raise(SIGINT);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
alreadyLocked = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trylock() {
|
||||||
|
#ifdef WIN32
|
||||||
|
if (Glib::RecMutex::trylock())
|
||||||
|
#else
|
||||||
|
if (Glib::Threads::RecMutex::trylock())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if STRICT_MUTEX || !defined(NDEBUG)
|
||||||
|
if (alreadyLocked) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
printf("Warning: MyMutex already locked!\n"); // breakpoint
|
||||||
|
#endif
|
||||||
|
#if STRICT_MUTEX
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#ifdef WIN32
|
||||||
|
DebugBreak();
|
||||||
|
#else
|
||||||
|
raise(SIGTRAP);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
raise(SIGINT);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
alreadyLocked = true;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning: the base class of MyMutex is RecMutex, but the mutex is said "unlocked" on first occurrence of "unlock", to avoid overhead.
|
||||||
|
void unlock() {
|
||||||
|
#if STRICT_MUTEX || !defined(NDEBUG)
|
||||||
|
alreadyLocked = false;
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32
|
||||||
|
Glib::RecMutex::unlock();
|
||||||
|
#else
|
||||||
|
Glib::Threads::RecMutex::unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class copied from the Glibmm source code, to provide a workaround of the behavior's difference between Linux and Windows
|
||||||
|
class MyMutex::MyLock {
|
||||||
|
public:
|
||||||
|
explicit inline MyLock(MyMutex& mutex) : mutex_ (mutex), locked_ (true) { mutex_.lock(); }
|
||||||
|
#ifdef WIN32
|
||||||
|
inline MyLock(MyMutex& mutex, Glib::NotLock) : mutex_ (mutex), locked_ (false) {}
|
||||||
|
inline MyLock(MyMutex& mutex, Glib::TryLock) : mutex_ (mutex), locked_ (mutex.trylock()) {}
|
||||||
|
#else
|
||||||
|
inline MyLock(MyMutex& mutex, Glib::Threads::NotLock) : mutex_ (mutex), locked_ (false) {}
|
||||||
|
inline MyLock(MyMutex& mutex, Glib::Threads::TryLock) : mutex_ (mutex), locked_ (mutex.trylock()) {}
|
||||||
|
#endif
|
||||||
|
inline ~MyLock() { if(locked_) mutex_.unlock(); }
|
||||||
|
|
||||||
|
inline void acquire() { mutex_.lock(); locked_ = true; }
|
||||||
|
inline bool try_acquire() { locked_ = mutex_.trylock(); return locked_; }
|
||||||
|
inline void release() { mutex_.unlock(); locked_ = false; }
|
||||||
|
inline bool locked() const { return locked_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
MyMutex& mutex_;
|
||||||
|
bool locked_;
|
||||||
|
|
||||||
|
// noncopyable
|
||||||
|
MyLock(const MyMutex::Lock&);
|
||||||
|
MyMutex::Lock& operator=(const MyMutex::Lock&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom RWLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
||||||
|
*
|
||||||
|
* It may be slower, but thread safe!
|
||||||
|
*/
|
||||||
|
class MyRWMutex {
|
||||||
|
public:
|
||||||
|
#ifdef WIN32
|
||||||
|
Glib::Mutex handlerMutex; // Having a recursive or non-recursive mutex is not important here, so we can use Glib::Mutex
|
||||||
|
Glib::Cond access;
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex handlerMutex; // Having a recursive or non-recursive mutex is not important here, so we can use Glib::Threads::Mutex
|
||||||
|
Glib::Threads::Cond access;
|
||||||
|
#endif
|
||||||
|
size_t writerCount;
|
||||||
|
size_t readerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
Glib::ustring lastWriterFile;
|
||||||
|
int lastWriterLine;
|
||||||
|
// Unfortunately, ownerThread may not be the culprit of a deadlock, it can be another concurrent Reader...
|
||||||
|
void* ownerThread;
|
||||||
|
|
||||||
|
MyRWMutex() : writerCount(0), readerCount(0), lastWriterLine(0), ownerThread(NULL) {}
|
||||||
|
#else
|
||||||
|
MyRWMutex() : writerCount(0), readerCount(0) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom ReaderLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class MyReaderLock {
|
||||||
|
|
||||||
|
MyRWMutex& rwMutex;
|
||||||
|
bool locked;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
static unsigned int readerLockCounter;
|
||||||
|
int locknumber;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline MyReaderLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0)
|
||||||
|
#else
|
||||||
|
public:
|
||||||
|
inline MyReaderLock(MyRWMutex& mutex) : rwMutex(mutex)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
locknumber = readerLockCounter++;
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.writerCount) {
|
||||||
|
// There's no writer operating, we can increment the writer count which will lock writers
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " ++ new owner";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The writer count is non null, but we can be the owner of the writer lock
|
||||||
|
// It will be the case if the reader count is non null too.
|
||||||
|
if (!rwMutex.readerCount) {
|
||||||
|
// the mutex is in real write mode, we're waiting to see it null
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
||||||
|
#endif
|
||||||
|
while (rwMutex.writerCount)
|
||||||
|
rwMutex.access.wait(rwMutex.handlerMutex);
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = file;
|
||||||
|
rwMutex.lastWriterLine = line;
|
||||||
|
rwMutex.ownerThread = thread;
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R ++ new owner";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then we can increment the reader count
|
||||||
|
++rwMutex.readerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
||||||
|
inline void acquire(const char* file, const int line)
|
||||||
|
#else
|
||||||
|
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
||||||
|
inline void acquire()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (!locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock)";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.writerCount) {
|
||||||
|
// There's no writer operating, we can increment the writer count which will lock writers
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " ++ new owner";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The writer count is non null, but a reader can be the owner of the writer lock,
|
||||||
|
// it will be the case if the reader count is non null too.
|
||||||
|
if (!rwMutex.readerCount) {
|
||||||
|
// the mutex is in real write mode, we're waiting to see it null
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
||||||
|
#endif
|
||||||
|
while (rwMutex.writerCount)
|
||||||
|
rwMutex.access.wait(rwMutex.handlerMutex);
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = file;
|
||||||
|
rwMutex.lastWriterLine = line;
|
||||||
|
rwMutex.ownerThread = thread;
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock) ++ new owner";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then we can increment the reader count
|
||||||
|
++rwMutex.readerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already locked by this object - R (lock)" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
inline ~MyReaderLock() {
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
// decrement the writer number first
|
||||||
|
--rwMutex.readerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << " / unlocking - R - ReaderCount: " << rwMutex.readerCount;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.readerCount) {
|
||||||
|
// no more reader, so we decrement the writer count
|
||||||
|
--rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = "";
|
||||||
|
rwMutex.lastWriterLine = 0;
|
||||||
|
rwMutex.ownerThread = NULL;
|
||||||
|
std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount;
|
||||||
|
#endif
|
||||||
|
// and signal the next waiting reader/writer that it's free
|
||||||
|
rwMutex.access.broadcast();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - R" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
||||||
|
inline void release(const char* file, const int line)
|
||||||
|
#else
|
||||||
|
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
||||||
|
inline void release()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
// decrement the writer number first
|
||||||
|
--rwMutex.readerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << " / unlocking - R (release) - ReaderCount: " << rwMutex.readerCount;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.readerCount) {
|
||||||
|
// no more reader, so we decrement the writer count
|
||||||
|
--rwMutex.writerCount;
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = "";
|
||||||
|
rwMutex.lastWriterLine = 0;
|
||||||
|
rwMutex.ownerThread = NULL;
|
||||||
|
std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount;
|
||||||
|
#endif
|
||||||
|
// and signal the next waiting reader/writer that it's free
|
||||||
|
rwMutex.access.broadcast();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already unlocked - R (release)" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Custom WriterLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class MyWriterLock {
|
||||||
|
|
||||||
|
MyRWMutex& rwMutex;
|
||||||
|
bool locked;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
static unsigned int writerLockCounter;
|
||||||
|
int locknumber;
|
||||||
|
public:
|
||||||
|
inline MyWriterLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0)
|
||||||
|
#else
|
||||||
|
public:
|
||||||
|
inline MyWriterLock(MyRWMutex& mutex) : rwMutex(mutex)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
locknumber = writerLockCounter++;
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - W";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rwMutex.writerCount) {
|
||||||
|
// The writer count is non null, so we have to wait for it to be null again
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
||||||
|
#endif
|
||||||
|
while (rwMutex.writerCount)
|
||||||
|
rwMutex.access.wait(rwMutex.handlerMutex);
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// then we can increment the writer count
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = file;
|
||||||
|
rwMutex.lastWriterLine = line;
|
||||||
|
rwMutex.ownerThread = thread;
|
||||||
|
std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
||||||
|
inline void acquire(const char* file, const int line)
|
||||||
|
#else
|
||||||
|
// locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely
|
||||||
|
inline void acquire()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (!locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rwMutex.writerCount) {
|
||||||
|
// The writer count is non null, so we have to wait for it to be null again
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl;
|
||||||
|
#endif
|
||||||
|
while (rwMutex.writerCount)
|
||||||
|
rwMutex.access.wait(rwMutex.handlerMutex);
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// then we can increment the reader count
|
||||||
|
++rwMutex.writerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = file;
|
||||||
|
rwMutex.lastWriterLine = line;
|
||||||
|
rwMutex.ownerThread = thread;
|
||||||
|
std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = true;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already locked by this object - W (lock)" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
inline ~MyWriterLock() {
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
// decrement the writer number first
|
||||||
|
--rwMutex.writerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << " / unlocking - W";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.writerCount) {
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = "";
|
||||||
|
rwMutex.lastWriterLine = 0;
|
||||||
|
rwMutex.ownerThread = NULL;
|
||||||
|
std::cout << " -- new owner possible!";
|
||||||
|
#endif
|
||||||
|
// The writer count is null again, so we can wake up the next writer or reader
|
||||||
|
rwMutex.access.broadcast();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
||||||
|
inline void release(const char* file, const int line)
|
||||||
|
#else
|
||||||
|
// releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely
|
||||||
|
inline void release()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
void* thread = Glib::Thread::self();
|
||||||
|
#endif
|
||||||
|
if (locked) {
|
||||||
|
// to operate safely
|
||||||
|
rwMutex.handlerMutex.lock();
|
||||||
|
|
||||||
|
// decrement the writer number first
|
||||||
|
--rwMutex.writerCount;
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << thread << "/" << locknumber << " / unlocking - W (release)";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!rwMutex.writerCount) {
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
rwMutex.lastWriterFile = "";
|
||||||
|
rwMutex.lastWriterLine = 0;
|
||||||
|
rwMutex.ownerThread = NULL;
|
||||||
|
std::cout << " -- new owner possible!";
|
||||||
|
#endif
|
||||||
|
// The writer count is null again, so we can wake up the next writer or reader
|
||||||
|
rwMutex.access.broadcast();
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rwMutex.handlerMutex.unlock();
|
||||||
|
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W (release)" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if TRACE_MYRWMUTEX
|
||||||
|
#define MYREADERLOCK(ln, e) MyReaderLock ln(e, #e, __FILE__, __LINE__);
|
||||||
|
#define MYWRITERLOCK(ln, e) MyWriterLock ln(e, #e, __FILE__, __LINE__);
|
||||||
|
#define MYREADERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__);
|
||||||
|
#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__);
|
||||||
|
#define MYREADERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__);
|
||||||
|
#define MYWRITERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__);
|
||||||
|
#else
|
||||||
|
#define MYREADERLOCK(ln, e) MyReaderLock ln(e);
|
||||||
|
#define MYWRITERLOCK(ln, e) MyWriterLock ln(e);
|
||||||
|
#define MYREADERLOCK_ACQUIRE(ln) ln.acquire();
|
||||||
|
#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire();
|
||||||
|
#define MYREADERLOCK_RELEASE(ln) ln.release();
|
||||||
|
#define MYWRITERLOCK_RELEASE(ln) ln.release();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _THREADUTILS_ */
|
@ -22,7 +22,7 @@
|
|||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include "lwbuttonset.h"
|
#include "lwbuttonset.h"
|
||||||
#include "thumbnail.h"
|
#include "thumbnail.h"
|
||||||
#include "guiutils.h"
|
#include "threadutils.h"
|
||||||
|
|
||||||
class ThumbBrowserBase;
|
class ThumbBrowserBase;
|
||||||
class ThumbBrowserEntryBase {
|
class ThumbBrowserEntryBase {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "thumbimageupdater.h"
|
#include "thumbimageupdater.h"
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
@ -77,7 +78,13 @@ public:
|
|||||||
|
|
||||||
Glib::ThreadPool* threadPool_;
|
Glib::ThreadPool* threadPool_;
|
||||||
|
|
||||||
|
// Need to be a Glib::Threads::Mutex because used in a Glib::Threads::Cond object...
|
||||||
|
// This is the only exceptions in RT so far, MyMutex is used everywhere else
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex mutex_;
|
Glib::Mutex mutex_;
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex mutex_;
|
||||||
|
#endif
|
||||||
|
|
||||||
JobList jobs_;
|
JobList jobs_;
|
||||||
|
|
||||||
@ -85,7 +92,11 @@ public:
|
|||||||
|
|
||||||
bool inactive_waiting_;
|
bool inactive_waiting_;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Cond inactive_;
|
Glib::Cond inactive_;
|
||||||
|
#else
|
||||||
|
Glib::Threads::Cond inactive_;
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
processNextJob()
|
processNextJob()
|
||||||
@ -93,7 +104,11 @@ public:
|
|||||||
Job j;
|
Job j;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
Glib::Mutex::Lock lock(mutex_);
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex::Lock lock(mutex_);
|
||||||
|
#endif
|
||||||
|
|
||||||
// nothing to do; could be jobs have been removed
|
// nothing to do; could be jobs have been removed
|
||||||
if ( jobs_.empty() )
|
if ( jobs_.empty() )
|
||||||
@ -168,7 +183,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex::Lock lock(mutex_);
|
Glib::Mutex::Lock lock(mutex_);
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex::Lock lock(mutex_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if ( --active_ == 0 &&
|
if ( --active_ == 0 &&
|
||||||
inactive_waiting_ )
|
inactive_waiting_ )
|
||||||
@ -206,7 +226,11 @@ ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex::Lock lock(impl_->mutex_);
|
Glib::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#endif
|
||||||
|
|
||||||
// look up if an older version is in the queue
|
// look up if an older version is in the queue
|
||||||
Impl::JobList::iterator i(impl_->jobs_.begin());
|
Impl::JobList::iterator i(impl_->jobs_.begin());
|
||||||
@ -239,7 +263,11 @@ ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener)
|
|||||||
{
|
{
|
||||||
DEBUG("removeJobs(%p)",listener);
|
DEBUG("removeJobs(%p)",listener);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex::Lock lock(impl_->mutex_);
|
Glib::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#endif
|
||||||
|
|
||||||
for( Impl::JobList::iterator i(impl_->jobs_.begin()); i != impl_->jobs_.end(); )
|
for( Impl::JobList::iterator i(impl_->jobs_.begin()); i != impl_->jobs_.end(); )
|
||||||
{
|
{
|
||||||
@ -271,8 +299,11 @@ ThumbImageUpdater::removeAllJobs(void)
|
|||||||
{
|
{
|
||||||
DEBUG("stop");
|
DEBUG("stop");
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
Glib::Mutex::Lock lock(impl_->mutex_);
|
Glib::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#else
|
||||||
|
Glib::Threads::Mutex::Lock lock(impl_->mutex_);
|
||||||
|
#endif
|
||||||
|
|
||||||
impl_->jobs_.clear();
|
impl_->jobs_.clear();
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageDa
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
loadProcParams ();
|
loadProcParams ();
|
||||||
|
|
||||||
|
// should be safe to use the unprotected version of loadThumbnail, since we are in the constructor
|
||||||
_loadThumbnail ();
|
_loadThumbnail ();
|
||||||
generateExifDateTimeStrings ();
|
generateExifDateTimeStrings ();
|
||||||
|
|
||||||
@ -165,11 +167,12 @@ bool Thumbnail::isSupported () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ProcParams& Thumbnail::getProcParams () {
|
const ProcParams& Thumbnail::getProcParams () {
|
||||||
// TODO: Check for Linux
|
MyMutex::MyLock lock(mutex);
|
||||||
#ifdef WIN32
|
return getProcParamsU();
|
||||||
Glib::Mutex::Lock lock(mutex);
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// Unprotected version of getProcParams, when
|
||||||
|
const ProcParams& Thumbnail::getProcParamsU () {
|
||||||
if (pparamsValid)
|
if (pparamsValid)
|
||||||
return pparams;
|
return pparams;
|
||||||
else {
|
else {
|
||||||
@ -239,10 +242,7 @@ void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt){
|
|||||||
* ProcParams (sidecar or cache file).
|
* ProcParams (sidecar or cache file).
|
||||||
*/
|
*/
|
||||||
void Thumbnail::loadProcParams () {
|
void Thumbnail::loadProcParams () {
|
||||||
// TODO: Check for Linux
|
MyMutex::MyLock lock(mutex);
|
||||||
#ifdef WIN32
|
|
||||||
Glib::Mutex::Lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pparamsValid = false;
|
pparamsValid = false;
|
||||||
pparams.setDefaults();
|
pparams.setDefaults();
|
||||||
@ -279,10 +279,8 @@ void Thumbnail::clearProcParams (int whoClearedIt) {
|
|||||||
(the CPB is NOT called) to set the params values and will preserve
|
(the CPB is NOT called) to set the params values and will preserve
|
||||||
rank/colorlabel/inTrash in the param file. */
|
rank/colorlabel/inTrash in the param file. */
|
||||||
|
|
||||||
// TODO: Check for Linux
|
{
|
||||||
#ifdef WIN32
|
MyMutex::MyLock lock(mutex);
|
||||||
Glib::Mutex::Lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// preserve rank, colorlabel and inTrash across clear
|
// preserve rank, colorlabel and inTrash across clear
|
||||||
int rank = getRank();
|
int rank = getRank();
|
||||||
@ -326,6 +324,8 @@ void Thumbnail::clearProcParams (int whoClearedIt) {
|
|||||||
safe_g_remove (fname_);
|
safe_g_remove (fname_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // end of mutex lock
|
||||||
|
|
||||||
for (size_t i=0; i<listeners.size(); i++)
|
for (size_t i=0; i<listeners.size(); i++)
|
||||||
listeners[i]->procParamsChanged (this, whoClearedIt);
|
listeners[i]->procParamsChanged (this, whoClearedIt);
|
||||||
}
|
}
|
||||||
@ -336,10 +336,9 @@ bool Thumbnail::hasProcParams () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoChangedIt, bool updateCacheNow) {
|
void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoChangedIt, bool updateCacheNow) {
|
||||||
// TODO: Check for Linux
|
|
||||||
#ifdef WIN32
|
{
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pparams.sharpening.threshold.isDouble() != pp.sharpening.threshold.isDouble())
|
if (pparams.sharpening.threshold.isDouble() != pp.sharpening.threshold.isDouble())
|
||||||
printf("WARNING: Sharpening different!\n");
|
printf("WARNING: Sharpening different!\n");
|
||||||
@ -368,6 +367,8 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh
|
|||||||
if (updateCacheNow)
|
if (updateCacheNow)
|
||||||
updateCache ();
|
updateCache ();
|
||||||
|
|
||||||
|
} // end of mutex lock
|
||||||
|
|
||||||
for (size_t i=0; i<listeners.size(); i++)
|
for (size_t i=0; i<listeners.size(); i++)
|
||||||
listeners[i]->procParamsChanged (this, whoChangedIt);
|
listeners[i]->procParamsChanged (this, whoChangedIt);
|
||||||
}
|
}
|
||||||
@ -401,14 +402,14 @@ bool Thumbnail::isEnqueued () {
|
|||||||
|
|
||||||
void Thumbnail::increaseRef ()
|
void Thumbnail::increaseRef ()
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
++ref;
|
++ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thumbnail::decreaseRef ()
|
void Thumbnail::decreaseRef ()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
if ( ref == 0 )
|
if ( ref == 0 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -429,10 +430,7 @@ void Thumbnail::getThumbnailSize (int &w, int &h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) {
|
void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) {
|
||||||
// TODO: Check for Linux
|
MyMutex::MyLock lock(mutex);
|
||||||
#ifdef WIN32
|
|
||||||
Glib::Mutex::Lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions
|
// WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions
|
||||||
double fw = lastW*lastScale;
|
double fw = lastW*lastScale;
|
||||||
@ -455,26 +453,21 @@ void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, i
|
|||||||
|
|
||||||
rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) {
|
rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
|
|
||||||
if ( tpp == 0 )
|
if ( tpp == 0 ) {
|
||||||
{
|
|
||||||
_loadThumbnail();
|
_loadThumbnail();
|
||||||
if ( tpp == 0 )
|
if ( tpp == 0 )
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rtengine::IImage8* image = 0;
|
rtengine::IImage8* image = 0;
|
||||||
|
|
||||||
if ( cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL )
|
if ( cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL ) {
|
||||||
{
|
|
||||||
// RAW internal thumbnail, no profile yet: just do some rotation etc.
|
// RAW internal thumbnail, no profile yet: just do some rotation etc.
|
||||||
image = tpp->quickProcessImage (pparams, h, rtengine::TI_Nearest, scale);
|
image = tpp->quickProcessImage (pparams, h, rtengine::TI_Nearest, scale);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// Full thumbnail: apply profile
|
// Full thumbnail: apply profile
|
||||||
image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.camera, cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale );
|
image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.camera, cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale );
|
||||||
}
|
}
|
||||||
@ -488,7 +481,7 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro
|
|||||||
|
|
||||||
rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) {
|
rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) {
|
||||||
|
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
|
|
||||||
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL )
|
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL )
|
||||||
{
|
{
|
||||||
@ -678,7 +671,7 @@ void Thumbnail::_loadThumbnail(bool firstTrial) {
|
|||||||
tpp->init ();
|
tpp->init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initial_ && tpp) tw = tpp->getImageWidth (getProcParams(), th, imgRatio); // this might return 0 if image was just building
|
if (!initial_ && tpp) tw = tpp->getImageWidth (getProcParamsU(), th, imgRatio); // this might return 0 if image was just building
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -690,7 +683,7 @@ void Thumbnail::_loadThumbnail(bool firstTrial) {
|
|||||||
* - LiveThumbData section of the data file
|
* - LiveThumbData section of the data file
|
||||||
*/
|
*/
|
||||||
void Thumbnail::loadThumbnail (bool firstTrial) {
|
void Thumbnail::loadThumbnail (bool firstTrial) {
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
_loadThumbnail(firstTrial);
|
_loadThumbnail(firstTrial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,7 +730,7 @@ void Thumbnail::_saveThumbnail () {
|
|||||||
*/
|
*/
|
||||||
void Thumbnail::saveThumbnail ()
|
void Thumbnail::saveThumbnail ()
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
_saveThumbnail();
|
_saveThumbnail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,13 +753,11 @@ void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Thumbnail::~Thumbnail () {
|
Thumbnail::~Thumbnail () {
|
||||||
// TODO: Check for Linux
|
mutex.lock();
|
||||||
#ifdef WIN32
|
|
||||||
Glib::Mutex::Lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete [] lastImg;
|
delete [] lastImg;
|
||||||
delete tpp;
|
delete tpp;
|
||||||
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::ustring Thumbnail::getCacheFileName (Glib::ustring subdir) {
|
Glib::ustring Thumbnail::getCacheFileName (Glib::ustring subdir) {
|
||||||
@ -860,7 +851,7 @@ bool Thumbnail::openDefaultViewer(int destination) {
|
|||||||
|
|
||||||
bool Thumbnail::imageLoad(bool loading)
|
bool Thumbnail::imageLoad(bool loading)
|
||||||
{
|
{
|
||||||
Glib::Mutex::Lock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
bool previous = imageLoading;
|
bool previous = imageLoading;
|
||||||
if( loading && !previous ){
|
if( loading && !previous ){
|
||||||
imageLoading = true;
|
imageLoading = true;
|
||||||
|
@ -27,11 +27,12 @@
|
|||||||
#include "../rtengine/rtthumbnail.h"
|
#include "../rtengine/rtthumbnail.h"
|
||||||
#include "cacheimagedata.h"
|
#include "cacheimagedata.h"
|
||||||
#include "thumbnaillistener.h"
|
#include "thumbnaillistener.h"
|
||||||
|
#include "threadutils.h"
|
||||||
|
|
||||||
class CacheManager;
|
class CacheManager;
|
||||||
class Thumbnail {
|
class Thumbnail {
|
||||||
|
|
||||||
Glib::Mutex mutex;
|
MyMutex mutex;
|
||||||
|
|
||||||
Glib::ustring fname; // file name corresponding to the thumbnail
|
Glib::ustring fname; // file name corresponding to the thumbnail
|
||||||
CacheImageData cfs; // cache entry corresponding to the thumbnail
|
CacheImageData cfs; // cache entry corresponding to the thumbnail
|
||||||
@ -82,6 +83,7 @@ class Thumbnail {
|
|||||||
|
|
||||||
bool hasProcParams ();
|
bool hasProcParams ();
|
||||||
const rtengine::procparams::ProcParams& getProcParams ();
|
const rtengine::procparams::ProcParams& getProcParams ();
|
||||||
|
const rtengine::procparams::ProcParams& getProcParamsU (); // Unprotected version
|
||||||
|
|
||||||
// Use this to create params on demand for update
|
// Use this to create params on demand for update
|
||||||
rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool forceCPB);
|
rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool forceCPB);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user