[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    extragear/graphics/digikam/libs
From:       Marcel Wiesweg <marcel.wiesweg () gmx ! de>
Date:       2009-08-09 16:06:09
Message-ID: 1249833969.117594.8212.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1009290 by mwiesweg:

LittleCMS boasts to be thread-safe but there are reports that it is not and certain methods
(those returning a static buffer) are definitely not.
Dont run a risk and use a mutex for Lcms calls.

 M  +22 -1     dimg/filters/iccprofile.cpp  
 M  +9 -0      dimg/filters/iccprofile.h  
 M  +3 -0      widgets/iccprofiles/cietonguewidget.cpp  
 M  +1 -0      widgets/iccprofiles/iccprofilewidget.cpp  


--- trunk/extragear/graphics/digikam/libs/dimg/filters/iccprofile.cpp #1009289:1009290
@@ -33,10 +33,12 @@
 
 #include <QDir>
 #include <QFile>
+#include <QMutex>
 
 // KDE includes
 
 #include <kdebug.h>
+#include <kglobal.h>
 #include <kstandarddirs.h>
 
 // Local includes
@@ -78,6 +80,7 @@
     {
         if (handle)
         {
+            LcmsLock lock();
             cmsCloseProfile(handle);
             handle = 0;
         }
@@ -89,6 +92,18 @@
     cmsHPROFILE handle;
 };
 
+K_GLOBAL_STATIC_WITH_ARGS(QMutex, lcmsMutex, (QMutex::Recursive))
+
+LcmsLock::LcmsLock()
+{
+    lcmsMutex->lock();
+}
+
+LcmsLock::~LcmsLock()
+{
+    lcmsMutex->unlock();
+}
+
 IccProfile::IccProfile()
             : d(0)
 {
@@ -234,6 +249,7 @@
 
     if (!d->data.isEmpty())
     {
+        LcmsLock lock();
         d->handle = cmsOpenProfileFromMem(d->data.data(), (DWORD)d->data.size());
     }
     else if (!d->filePath.isNull())
@@ -243,6 +259,7 @@
 
         if (d->data.isEmpty())
             return false;
+        LcmsLock lock();
         d->handle = cmsOpenProfileFromMem(d->data.data(), (DWORD)d->data.size());
     }
 
@@ -278,7 +295,10 @@
     if (!d)
         return QString();
 
-    open();
+    if (!open())
+        return QString();
+
+    LcmsLock lock();
     const char *desc = cmsTakeProductDesc(d->handle);
     if (desc && desc[0] != '\0')
         return QString::fromLatin1(desc);
@@ -293,6 +313,7 @@
     if (!open())
         return InvalidType;
 
+    LcmsLock lock();
     switch ((int)cmsGetDeviceClass(d->handle))
     {
         case icSigInputClass:
--- trunk/extragear/graphics/digikam/libs/dimg/filters/iccprofile.h #1009289:1009290
@@ -164,7 +164,16 @@
     QSharedDataPointer<IccProfilePriv> d;
 };
 
+class DIGIKAM_EXPORT LcmsLock
+{
+public:
 
+    /** Obtain an LcmsLock if you access not clearly thread-safe LittleCMS methods */
+    LcmsLock();
+    ~LcmsLock();
+};
+
+
 }  // namespace Digikam
 
 #endif   // ICCPROFILE_H
--- trunk/extragear/graphics/digikam/libs/widgets/iccprofiles/cietonguewidget.cpp #1009289:1009290
@@ -48,6 +48,7 @@
 
 // Local includes
 
+#include "iccprofile.h"
 #include "lcmsprf.h"
 
 namespace Digikam
@@ -247,6 +248,7 @@
 {
     if (!profileData.isEmpty())
     {
+        LcmsLock lock();
         cmsHPROFILE hProfile = cmsOpenProfileFromMem((void*)profileData.data(),
                                                     (DWORD)profileData.size());
 
@@ -281,6 +283,7 @@
 {
     if (!file.isEmpty() && file.isValid())
     {
+        LcmsLock lock();
         cmsHPROFILE hProfile = cmsOpenProfileFromFile(QFile::encodeName(file.path()), "r");
 
         if (!hProfile)
--- trunk/extragear/graphics/digikam/libs/widgets/iccprofiles/iccprofilewidget.cpp #1009289:1009290
@@ -271,6 +271,7 @@
 
     d->cieTongue->setProfileData(d->profile.data());
 
+    LcmsLock lock();
     cmsHPROFILE hProfile = d->profile.handle();
 
     if (!hProfile)
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic