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 22:24:00 UTC
[03/15] 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
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;
}
}