This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2c70be3  GEODE-7316: Fix nc shutdown crash (#539)
2c70be3 is described below

commit 2c70be377941487a5ff45eccea04ef65a51dd61c
Author: Blake Bender <[email protected]>
AuthorDate: Mon Oct 21 22:20:34 2019 +0000

    GEODE-7316: Fix nc shutdown crash (#539)
---
 cppcache/include/geode/Cache.hpp       |  2 +-
 cppcache/src/CacheImpl.cpp             | 56 ++++++++++++++++++++--------------
 cppcache/src/CacheImpl.hpp             |  9 +++---
 cppcache/src/CachePerfStats.hpp        |  3 ++
 cppcache/src/ClientMetadataService.cpp | 10 +++---
 5 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/cppcache/include/geode/Cache.hpp b/cppcache/include/geode/Cache.hpp
index 3a0635c..f1f1d6b 100644
--- a/cppcache/include/geode/Cache.hpp
+++ b/cppcache/include/geode/Cache.hpp
@@ -254,7 +254,7 @@ class APACHE_GEODE_EXPORT Cache : public GeodeCache {
         bool readPdxSerialized,
         const std::shared_ptr<AuthInitialize>& authInitialize);
 
-  std::unique_ptr<CacheImpl> m_cacheImpl;
+  std::shared_ptr<CacheImpl> m_cacheImpl;
 
  protected:
   static bool isPoolInMultiuserMode(std::shared_ptr<Region> regionPtr);
diff --git a/cppcache/src/CacheImpl.cpp b/cppcache/src/CacheImpl.cpp
index 168a23c..caeec99 100644
--- a/cppcache/src/CacheImpl.cpp
+++ b/cppcache/src/CacheImpl.cpp
@@ -19,6 +19,8 @@
 
 #include <string>
 
+#include <ace/Guard_T.h>
+
 #include <geode/CacheStatistics.hpp>
 #include <geode/PersistenceManager.hpp>
 #include <geode/PoolManager.hpp>
@@ -162,7 +164,7 @@ CacheImpl::RegionKind CacheImpl::getRegionKind(
 }
 
 void CacheImpl::removeRegion(const std::string& name) {
-  TryReadGuard guardCacheDestroy(m_destroyCacheMutex, m_destroyPending);
+  ACE_Guard<ACE_Recursive_Thread_Mutex> lock(m_destroyCacheMutex, 1);
   if (!m_destroyPending) {
     m_regions.erase(name);
   }
@@ -240,15 +242,18 @@ void CacheImpl::close(bool keepalive) {
   TcrMessage::setKeepAlive(keepalive);
   // bug #247 fix for durable clients missing events when recycled
   sendNotificationCloseMsgs();
+
   {
-    TryWriteGuard guardCacheDestroy(m_destroyCacheMutex, m_destroyPending);
+    ACE_Guard<ACE_Recursive_Thread_Mutex> lock(m_destroyCacheMutex, 1);
     if (m_destroyPending) {
       return;
     }
     m_destroyPending = true;
   }
 
-  if (m_closed || (!m_initialized)) return;
+  if (m_closed || (!m_initialized)) {
+    return;
+  }
 
   // Close the distribution manager used for queries.
   if (m_remoteQueryServicePtr != nullptr) {
@@ -324,14 +329,21 @@ void CacheImpl::close(bool keepalive) {
   LOGFINE("Cache closed.");
 }
 
-bool CacheImpl::isCacheDestroyPending() const { return m_destroyPending; }
+bool CacheImpl::doIfDestroyNotPending(std::function<void()> f) {
+  ACE_Guard<ACE_Recursive_Thread_Mutex> lock(m_destroyCacheMutex, 1);
+  if (lock.locked() && !m_destroyPending) {
+    f();
+  }
+
+  return !m_destroyPending;
+}
 
 void CacheImpl::validateRegionAttributes(
     const std::string& name, const RegionAttributes& regionAttributes) const {
   auto&& kind = getRegionKind(regionAttributes);
   if (regionAttributes.m_clientNotificationEnabled && kind == CPP_REGION) {
     throw UnsupportedOperationException(
-        "Cache::createRegion: \"" + name +
+        "CacheImpl::createRegion: \"" + name +
         "\" Client notification can be enabled only for native client region");
   }
 }
@@ -370,7 +382,7 @@ void CacheImpl::createRegion(std::string name,
     auto&& lock = m_regions.make_lock();
 
     if (m_regions.find(name) != m_regions.end()) {
-      throw RegionExistsException("Cache::createRegion: \"" + name +
+      throw RegionExistsException("CacheImpl::createRegion: \"" + name +
                                   "\" region exists in local cache");
     }
 
@@ -385,17 +397,18 @@ void CacheImpl::createRegion(std::string name,
     } catch (const Exception&) {
       throw;
     } catch (std::exception& ex) {
-      throw UnknownException("Cache::createRegion: Failed to create Region \"" 
+
-                             name +
-                             "\" due to unknown exception: " + ex.what());
+      throw UnknownException(
+          "CacheImpl::createRegion: Failed to create Region \"" + name +
+          "\" due to unknown exception: " + ex.what());
     } catch (...) {
-      throw UnknownException("Cache::createRegion: Failed to create Region \"" 
+
-                             name + "\" due to unknown exception.");
+      throw UnknownException(
+          "CacheImpl::createRegion: Failed to create Region \"" + name +
+          "\" due to unknown exception.");
     }
 
     if (rpImpl == nullptr) {
       throw RegionCreationFailedException(
-          "Cache::createRegion: Failed to create Region \"" + name + "\"");
+          "CacheImpl::createRegion: Failed to create Region \"" + name + "\"");
     }
 
     regionPtr = rpImpl;
@@ -449,11 +462,10 @@ std::shared_ptr<Region> CacheImpl::findRegion(const 
std::string& name) {
 }
 
 std::shared_ptr<Region> CacheImpl::getRegion(const std::string& path) {
-  LOGDEBUG("Cache::getRegion " + path);
+  LOGDEBUG("CacheImpl::getRegion " + path);
 
   this->throwIfClosed();
-
-  TryReadGuard guardCacheDestroy(m_destroyCacheMutex, m_destroyPending);
+  ACE_Guard<ACE_Recursive_Thread_Mutex> lock(m_destroyCacheMutex, 1);
 
   if (m_destroyPending) {
     return nullptr;
@@ -461,7 +473,7 @@ std::shared_ptr<Region> CacheImpl::getRegion(const 
std::string& path) {
 
   static const std::string slash("/");
   if (path == slash || path.length() < 1) {
-    LOGERROR("Cache::getRegion: path [" + path + "] is not valid.");
+    LOGERROR("CacheImpl::getRegion: path [" + path + "] is not valid.");
     throw IllegalArgumentException("Cache::getRegion: path is empty or a /");
   }
 
@@ -597,14 +609,12 @@ void CacheImpl::readyForEvents() {
   bool isDurable = m_tcrConnectionManager->isDurable();
 
   if (!isDurable && autoReadyForEvents) {
-    LOGERROR(
-        "Only durable clients or clients with the "
-        "auto-ready-for-events property set to false should call "
-        "readyForEvents()");
-    throw IllegalStateException(
+    std::string msg =
         "Only durable clients or clients with the "
         "auto-ready-for-events property set to false should call "
-        "readyForEvents()");
+        "readyForEvents()";
+    LOGERROR("CacheImpl::%s(%p): %s", __FUNCTION__, this, msg.c_str());
+    throw IllegalStateException(msg.c_str());
   }
 
   // Send the CLIENT_READY message to the server
@@ -670,7 +680,7 @@ bool CacheImpl::getEndpointStatus(const std::string& 
endpoint) {
 }
 
 void CacheImpl::processMarker() {
-  TryReadGuard guardCacheDestroy(m_destroyCacheMutex, m_destroyPending);
+  ACE_Guard<ACE_Recursive_Thread_Mutex> destroy_lock(m_destroyCacheMutex, 1);
   if (m_destroyPending) {
     return;
   }
diff --git a/cppcache/src/CacheImpl.hpp b/cppcache/src/CacheImpl.hpp
index bd718b6..b5f4441 100644
--- a/cppcache/src/CacheImpl.hpp
+++ b/cppcache/src/CacheImpl.hpp
@@ -24,7 +24,7 @@
 #include <memory>
 #include <mutex>
 
-#include <ace/RW_Thread_Mutex.h>
+#include <ace/Recursive_Thread_Mutex.h>
 
 #include <geode/Cache.hpp>
 #include <geode/PoolManager.hpp>
@@ -272,8 +272,6 @@ class APACHE_GEODE_EXPORT CacheImpl : private NonCopyable,
     return m_readPdxSerialized;
   }
 
-  bool isCacheDestroyPending() const;
-
   static std::map<std::string, RegionAttributes> getRegionShortcut();
 
   std::shared_ptr<PdxTypeRegistry> getPdxTypeRegistry() const;
@@ -322,6 +320,8 @@ class APACHE_GEODE_EXPORT CacheImpl : private NonCopyable,
       std::shared_ptr<Properties> userSecurityProperties,
       const std::string& poolName);
 
+  bool doIfDestroyNotPending(std::function<void()>);
+
  private:
   std::atomic<bool> m_networkhop;
   std::atomic<int> m_blacklistBucketTimeout;
@@ -374,7 +374,7 @@ class APACHE_GEODE_EXPORT CacheImpl : private NonCopyable,
   std::unique_ptr<EvictionController> m_evictionController;
   TcrConnectionManager* m_tcrConnectionManager;
   std::shared_ptr<RemoteQueryService> m_remoteQueryServicePtr;
-  ACE_RW_Thread_Mutex m_destroyCacheMutex;
+  ACE_Recursive_Thread_Mutex m_destroyCacheMutex;
   volatile bool m_destroyPending;
   volatile bool m_initDone;
   std::mutex m_initDoneLock;
@@ -397,6 +397,7 @@ class APACHE_GEODE_EXPORT CacheImpl : private NonCopyable,
   friend class CacheFactory;
   friend class Cache;
   friend class DistributedSystemImpl;
+  friend class PdxInstanceFactory;
 };
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/src/CachePerfStats.hpp b/cppcache/src/CachePerfStats.hpp
index 9c7ad7e..3bd633b 100644
--- a/cppcache/src/CachePerfStats.hpp
+++ b/cppcache/src/CachePerfStats.hpp
@@ -201,6 +201,9 @@ class APACHE_GEODE_EXPORT CachePerfStats {
     m_cachePerfStats->setLong(m_pdxDeserializedBytesId, 0);
   }
 
+  CachePerfStats(const CachePerfStats& other) = default;
+  CachePerfStats(CachePerfStats&& other) = default;
+
   virtual ~CachePerfStats() { m_cachePerfStats = nullptr; }
 
   void close() {
diff --git a/cppcache/src/ClientMetadataService.cpp 
b/cppcache/src/ClientMetadataService.cpp
index bf78afa..191b9c6 100644
--- a/cppcache/src/ClientMetadataService.cpp
+++ b/cppcache/src/ClientMetadataService.cpp
@@ -81,10 +81,12 @@ void ClientMetadataService::svc() {
     m_regionQueue.pop_front();
     queue::coalesce(m_regionQueue, regionFullPath);
 
-    if (!m_cache->isCacheDestroyPending()) {
-      lock.unlock();
-      getClientPRMetadata(regionFullPath.c_str());
-    } else {
+    if (!m_cache->doIfDestroyNotPending([&]() {
+          lock.unlock();
+          getClientPRMetadata(regionFullPath.c_str());
+        })) {
+      LOGINFO("ClientMetadataService::%s(%p): destroy is pending, bail out",
+              __FUNCTION__, this);
       break;
     }
   }

Reply via email to