You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/17 16:03:26 UTC

[3/9] ignite git commit: IGNITE-5208: Fixed sigfault on concurrent map access

IGNITE-5208: Fixed sigfault on concurrent map access


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/82144631
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/82144631
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/82144631

Branch: refs/heads/ignite-5075-cacheStart
Commit: 821446317086102ab1f11633864f8d9c08c3bcba
Parents: e1f3e4a
Author: Igor Sapego <is...@gridgain.com>
Authored: Wed May 17 12:38:20 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Wed May 17 12:38:20 2017 +0300

----------------------------------------------------------------------
 .../ignite/impl/binary/binary_type_manager.h    |  6 +-
 .../src/impl/binary/binary_type_manager.cpp     | 83 +++++++++-----------
 2 files changed, 41 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/82144631/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_manager.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_manager.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_manager.h
index 01538b8..dc147fa 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_manager.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_type_manager.h
@@ -52,7 +52,7 @@ namespace ignite
                  * @param typeName Type name.
                  * @param typeId Type ID.
                  */
-                ignite::common::concurrent::SharedPointer<BinaryTypeHandler> GetHandler(const std::string& typeName, int32_t typeId);
+                common::concurrent::SharedPointer<BinaryTypeHandler> GetHandler(const std::string& typeName, int32_t typeId);
 
                 /**
                  * Submit handler for processing.
@@ -104,13 +104,13 @@ namespace ignite
 
             private:
                 /** Current snapshots. */
-                ignite::common::concurrent::SharedPointer<std::map<int32_t, SPSnap> > snapshots;
+                std::map<int32_t, SPSnap>* snapshots;
 
                 /** Pending snapshots. */
                 std::vector<SPSnap>* pending;
 
                 /** Critical section. */
-                ignite::common::concurrent::CriticalSection cs;
+                common::concurrent::CriticalSection cs;
 
                 /** Type updater */
                 BinaryTypeUpdater* updater;

http://git-wip-us.apache.org/repos/asf/ignite/blob/82144631/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
index 4a8c14c..98d4602 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
@@ -41,20 +41,17 @@ namespace ignite
 
             BinaryTypeManager::~BinaryTypeManager()
             {
-                pending->erase(pending->begin(), pending->end());
-
+                delete snapshots;
                 delete pending;
             }
 
             SharedPointer<BinaryTypeHandler> BinaryTypeManager::GetHandler(const std::string& typeName, int32_t typeId)
             {
-                std::map<int32_t, SPSnap>& snapshots0 = *snapshots.Get();
-
                 { // Locking scope.
                     CsLockGuard guard(cs);
 
-                    std::map<int32_t, SPSnap>::iterator it = snapshots0.find(typeId);
-                    if (it != snapshots0.end())
+                    std::map<int32_t, SPSnap>::iterator it = snapshots->find(typeId);
+                    if (it != snapshots->end())
                         return SharedPointer<BinaryTypeHandler>(new BinaryTypeHandler(it->second));
                 }
 
@@ -65,7 +62,7 @@ namespace ignite
 
             void BinaryTypeManager::SubmitHandler(BinaryTypeHandler& hnd)
             {
-                // If this is the very first write of a class or difference exists, 
+                // If this is the very first write of a class or difference exists,
                 // we need to enqueue it for write.
                 if (hnd.HasUpdate())
                 {
@@ -102,45 +99,30 @@ namespace ignite
                 {
                     Snap* pendingSnap = it->Get();
 
+                    if (!pendingSnap)
+                        continue; // Snapshot has been processed already.
+
                     if (!updater->Update(*pendingSnap, err))
                         return false; // Stop as we cannot move further.
 
-                    // Perform copy-on-write update of snapshot collection.
-                    SharedPointer< std::map<int32_t, SPSnap> > newSnapshots(new std::map<int32_t, SPSnap>());
-                    std::map<int32_t, SPSnap>& newSnapshots0 = *newSnapshots.Get();
+                    std::map<int32_t, SPSnap>::iterator elem = snapshots->lower_bound(pendingSnap->GetTypeId());
 
-                    bool snapshotFound = false;
-
-                    for (std::map<int32_t, SPSnap>::iterator snapIt = snapshots.Get()->begin();
-                        snapIt != snapshots.Get()->end(); ++snapIt)
+                    if (elem == snapshots->end() || elem->first != pendingSnap->GetTypeId())
+                        snapshots->insert(elem, std::make_pair(pendingSnap->GetTypeId(), *it));
+                    else
                     {
-                        int32_t curTypeId = snapIt->first;
-                        Snap* curSnap = snapIt->second.Get();
-
-                        if (pendingSnap->GetTypeId() != curTypeId)
-                        {
-                            // Just transfer exising snapshot.
-                            newSnapshots0[curTypeId] = snapIt->second;
+                        // Temporary snapshot.
+                        SPSnap tmp;
 
-                            continue;
-                        }
+                        // Move all values from pending update.
+                        tmp.Swap(*it);
 
-                        // Create new snapshot.
-                        SPSnap newSnap(new Snap(*pendingSnap));
+                        // Add old fields. Only non-existing values added.
+                        tmp.Get()->CopyFieldsFrom(elem->second.Get());
 
-                        // Add old fields.
-                        newSnap.Get()->CopyFieldsFrom(curSnap);
-
-                        newSnapshots0[curTypeId].Swap(newSnap);
-
-                        snapshotFound = true;
+                        // Move to snapshots storage.
+                        tmp.Swap(elem->second);
                     }
-
-                    // Handle situation when completely new snapshot is found.
-                    if (!snapshotFound)
-                        newSnapshots0[pendingSnap->GetTypeId()] = *it;
-
-                    snapshots.Swap(newSnapshots);
                 }
 
                 pending->clear();
@@ -152,17 +134,21 @@ namespace ignite
 
             SPSnap BinaryTypeManager::GetMeta(int32_t typeId)
             {
-                std::map<int32_t, SPSnap>::iterator it = snapshots.Get()->find(typeId);
+                { // Locking scope.
+                    CsLockGuard guard(cs);
 
-                if (it != snapshots.Get()->end() && it->second.Get())
-                    return it->second;
+                    std::map<int32_t, SPSnap>::iterator it = snapshots->find(typeId);
 
-                for (int32_t i = 0; i < pending->size(); ++i)
-                {
-                    SPSnap& snap = (*pending)[i];
+                    if (it != snapshots->end() && it->second.Get())
+                        return it->second;
 
-                    if (snap.Get()->GetTypeId() == typeId)
-                        return snap;
+                    for (int32_t i = 0; i < pending->size(); ++i)
+                    {
+                        SPSnap& snap = (*pending)[i];
+
+                        if (snap.Get()->GetTypeId() == typeId)
+                            return snap;
+                    }
                 }
 
                 IgniteError err;
@@ -171,6 +157,13 @@ namespace ignite
 
                 IgniteError::ThrowIfNeeded(err);
 
+                // Caching meta snapshot for faster access in future.
+                { // Locking scope.
+                    CsLockGuard guard(cs);
+
+                    snapshots->insert(std::make_pair(typeId, snap));
+                }
+
                 return snap;
             }
         }