[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:42:32 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=e5497c5

The following commit has been merged in the master branch:
commit e5497c5188e8170b084813739ebfb303b3e2a2d7
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Fri Jul 1 15:03:45 2011 +0000

    #439: Added optional parameters to XmpParser::initialize() to work around thread-safety issues (Jonathan Potter, GP Software)
---
 src/xmp.cpp | 27 ++++++++++++++++++++++++++-
 src/xmp.hpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/src/xmp.cpp b/src/xmp.cpp
index 55fc955..e58894e 100644
--- a/src/xmp.cpp
+++ b/src/xmp.cpp
@@ -101,6 +101,24 @@ namespace {
     //! Make an XMP key from a schema namespace and property path
     Exiv2::XmpKey::AutoPtr makeXmpKey(const std::string& schemaNs,
                                       const std::string& propPath);
+
+    //! Helper class used to serialize critical sections
+    class AutoLock
+    {
+    public:
+        AutoLock(Exiv2::XmpParser::XmpLockFct xmpLockFct, void* pLockData)
+            : xmpLockFct_(xmpLockFct), pLockData_(pLockData)
+        {
+            if (xmpLockFct_) xmpLockFct_(pLockData_, true);
+        }
+        ~AutoLock()
+        {
+            if (xmpLockFct_) xmpLockFct_(pLockData_, false);
+        }
+    private:
+        Exiv2::XmpParser::XmpLockFct xmpLockFct_;
+        void* pLockData_;
+    };
 }
 
 // *****************************************************************************
@@ -375,11 +393,15 @@ namespace Exiv2 {
     }
 
     bool XmpParser::initialized_ = false;
+    XmpParser::XmpLockFct XmpParser::xmpLockFct_ = 0;
+    void* XmpParser::pLockData_ = 0;
 
-    bool XmpParser::initialize()
+    bool XmpParser::initialize(XmpParser::XmpLockFct xmpLockFct, void* pLockData)
     {
         if (!initialized_) {
 #ifdef EXV_HAVE_XMP_TOOLKIT
+            xmpLockFct_ = xmpLockFct;
+            pLockData_ = pLockData;
             initialized_ = SXMPMeta::Initialize();
             SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/1.0/", "digiKam");
             SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/kipi/1.0/", "kipi");
@@ -402,6 +424,8 @@ namespace Exiv2 {
 #ifdef EXV_HAVE_XMP_TOOLKIT
             SXMPMeta::Terminate();
 #endif
+            xmpLockFct_ = 0;
+            pLockData_ = 0;
             initialized_ = false;
         }
     }
@@ -412,6 +436,7 @@ namespace Exiv2 {
     {
         try {
             initialize();
+            AutoLock autoLock(xmpLockFct_, pLockData_);
             SXMPMeta::DeleteNamespace(ns.c_str());
             SXMPMeta::RegisterNamespace(ns.c_str(), prefix.c_str());
         }
diff --git a/src/xmp.hpp b/src/xmp.hpp
index 184e206..dce2eeb 100644
--- a/src/xmp.hpp
+++ b/src/xmp.hpp
@@ -304,14 +304,68 @@ namespace Exiv2 {
                                 uint16_t     formatFlags =useCompactFormat,
                                 uint32_t     padding =0);
         /*!
+          @brief Lock/unlock function type
+
+          A function of this type can be passed to initialize() to
+          make subsequent registration of XMP namespaces thread-safe.
+          See the initialize() function for more information.
+
+          @param pLockData Pointer to the pLockData passed to initialize()
+          @param lockUnlock Indicates whether to lock (true) or unlock (false)
+         */
+        typedef void (*XmpLockFct)(void* pLockData, bool lockUnlock);
+
+        /*!
           @brief Initialize the XMP Toolkit.
 
           Calling this method is usually not needed, as encode() and
           decode() will initialize the XMP Toolkit if necessary.
 
+          The function takes optional pointers to a callback function
+          \em xmpLockFct and related data \em pLockData that the parser
+          uses when XMP namespaces are subsequently registered.
+
+          The initialize() function itself still is not thread-safe and
+          needs to be called in a thread-safe manner (e.g., on program
+          startup), but if used with suitable additional locking
+          parameters, any subsequent registration of namespaces will be
+          thread-safe.
+
+          Example usage on Windows using a critical section:
+
+          @code
+          void main()
+          {
+              struct XmpLock
+              {
+                  CRITICAL_SECTION cs;
+                  XmpLock()  { InitializeCriticalSection(&cs); }
+                  ~XmpLock() { DeleteCriticalSection(&cs); }
+
+                  static void LockUnlock(void* pData, bool fLock)
+                  {
+                      XmpLock* pThis = reinterpret_cast<XmpLock*>(pData);
+                      if (pThis)
+                      {
+                          (fLock) ? EnterCriticalSection(&pThis->cs)
+                                  : LeaveCriticalSection(&pThis->cs);
+                      }
+                  }
+              } xmpLock;
+
+              // Pass the locking mechanism to the XMP parser on initialization.
+              // Note however that this call itself is still not thread-safe.
+              Exiv2::XmpParser::initialize(XmpLock::LockUnlock, &xmpLock);
+
+              // Program continues here, subsequent registrations of XMP 
+              // namespaces are serialized using xmpLock.
+
+          }
+          @endcode
+
           @return True if the initialization was successful, else false.
          */
-        static bool initialize();
+        static bool initialize(XmpParser::XmpLockFct xmpLockFct =0, void* pLockData =0);
         /*!
           @brief Terminate the XMP Toolkit and unregister custom namespaces.
 
@@ -335,6 +389,8 @@ namespace Exiv2 {
 
         // DATA
         static bool initialized_; //! Indicates if the XMP Toolkit has been initialized
+        static XmpLockFct xmpLockFct_;
+        static void* pLockData_;
 
     }; // class XmpParser
 

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list