You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@brpc.apache.org by ja...@apache.org on 2020/12/07 04:40:32 UTC

[incubator-brpc] branch master updated: SimpleDataPool::Return resets data before returning back to pool

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

jamesge pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new fb93753  SimpleDataPool::Return resets data before returning back to pool
fb93753 is described below

commit fb93753bc54666fb815ed2fe099b0a98a01ea61e
Author: jamesge <jg...@gmail.com>
AuthorDate: Mon Dec 7 12:40:16 2020 +0800

    SimpleDataPool::Return resets data before returning back to pool
---
 src/brpc/data_factory.h                            |  15 ++-
 .../{simple_data_pool.h => simple_data_pool.cpp}   |  56 ++---------
 src/brpc/simple_data_pool.h                        | 111 ---------------------
 3 files changed, 21 insertions(+), 161 deletions(-)

diff --git a/src/brpc/data_factory.h b/src/brpc/data_factory.h
index 4fd8bf5..a487262 100644
--- a/src/brpc/data_factory.h
+++ b/src/brpc/data_factory.h
@@ -24,19 +24,24 @@
 
 namespace brpc {
 
+// ---- thread safety ----
+// Method implementations of this interface should be thread-safe
 class DataFactory {
 public:
     virtual ~DataFactory() {}
 
-    // Implement this method to create a piece of data.
-    // Notice that this method is const.
+    // Implement this method to create a piece of data
     // Returns the data, NULL on error.
     virtual void* CreateData() const = 0;
 
-    // Implement this method to destroy a piece of data that was created
-    // by Create().
-    // Notice that this method is const.
+    // Implement this method to destroy data created by Create().
     virtual void DestroyData(void*) const = 0;
+
+    // Overwrite this method to reset the data before reuse. Nothing done by default.
+    // Returns
+    //   true:  the data can be kept for future reuse
+    //   false: the data was already destroyed and should NOT be reused.
+    virtual bool ResetData(void*) const { return true; }
 };
 
 } // namespace brpc
diff --git a/src/brpc/simple_data_pool.h b/src/brpc/simple_data_pool.cpp
similarity index 69%
copy from src/brpc/simple_data_pool.h
copy to src/brpc/simple_data_pool.cpp
index 4ab3f1f..9374da4 100644
--- a/src/brpc/simple_data_pool.h
+++ b/src/brpc/simple_data_pool.cpp
@@ -16,46 +16,11 @@
 // under the License.
 
 
-#ifndef BRPC_SIMPLE_DATA_POOL_H
-#define BRPC_SIMPLE_DATA_POOL_H
-
-#include "butil/scoped_lock.h"
-#include "brpc/data_factory.h"
-
+#include "brpc/simple_data_pool.h"
 
 namespace brpc {
 
-// As the name says, this is a simple unbounded dynamic-size pool for
-// reusing void* data. We're assuming that data consumes considerable
-// memory and should be reused as much as possible, thus unlike the
-// multi-threaded allocator caching objects thread-locally, we just
-// put everything in a global list to maximize sharing. It's currently
-// used by Server to reuse session-local data. 
-class SimpleDataPool {
-public:
-    struct Stat {
-        unsigned nfree;
-        unsigned ncreated;
-    };
-
-    explicit SimpleDataPool(const DataFactory* factory);
-    ~SimpleDataPool();
-    void Reset(const DataFactory* factory);
-    void Reserve(unsigned n);
-    void* Borrow();
-    void Return(void*);
-    Stat stat() const;
-    
-private:
-    butil::Mutex _mutex;
-    unsigned _capacity;
-    unsigned _size;
-    butil::atomic<unsigned> _ncreated;
-    void** _pool;
-    const DataFactory* _factory;
-};
-
-inline SimpleDataPool::SimpleDataPool(const DataFactory* factory)
+SimpleDataPool::SimpleDataPool(const DataFactory* factory)
     : _capacity(0)
     , _size(0)
     , _ncreated(0)
@@ -63,11 +28,11 @@ inline SimpleDataPool::SimpleDataPool(const DataFactory* factory)
     , _factory(factory) {
 }
 
-inline SimpleDataPool::~SimpleDataPool() {
+SimpleDataPool::~SimpleDataPool() {
     Reset(NULL);
 }
 
-inline void SimpleDataPool::Reset(const DataFactory* factory) {
+void SimpleDataPool::Reset(const DataFactory* factory) {
     unsigned saved_size = 0;
     void** saved_pool = NULL;
     const DataFactory* saved_factory = NULL;
@@ -92,7 +57,7 @@ inline void SimpleDataPool::Reset(const DataFactory* factory) {
     }
 }
 
-inline void SimpleDataPool::Reserve(unsigned n) {
+void SimpleDataPool::Reserve(unsigned n) {
     if (_capacity >= n) {
         return;
     }
@@ -124,7 +89,7 @@ inline void SimpleDataPool::Reserve(unsigned n) {
     }
 }
 
-inline void* SimpleDataPool::Borrow() {
+void* SimpleDataPool::Borrow() {
     if (_size) {
         BAIDU_SCOPED_LOCK(_mutex);
         if (_size) {
@@ -138,10 +103,13 @@ inline void* SimpleDataPool::Borrow() {
     return data;
 }
 
-inline void SimpleDataPool::Return(void* data) {
+void SimpleDataPool::Return(void* data) {
     if (data == NULL) {
         return;
     }
+    if (!_factory->ResetData(data)) {
+        return;
+    }
     std::unique_lock<butil::Mutex> mu(_mutex);
     if (_capacity == _size) {
         const unsigned new_cap = (_capacity <= 1 ? 128 : (_capacity * 3 / 2));
@@ -160,12 +128,10 @@ inline void SimpleDataPool::Return(void* data) {
     _pool[_size++] = data;
 }
 
-inline SimpleDataPool::Stat SimpleDataPool::stat() const {
+SimpleDataPool::Stat SimpleDataPool::stat() const {
     Stat s = { _size, _ncreated.load(butil::memory_order_relaxed) };
     return s;
 }
 
 } // namespace brpc
 
-
-#endif  // BRPC_SIMPLE_DATA_POOL_H
diff --git a/src/brpc/simple_data_pool.h b/src/brpc/simple_data_pool.h
index 4ab3f1f..390f6e5 100644
--- a/src/brpc/simple_data_pool.h
+++ b/src/brpc/simple_data_pool.h
@@ -55,117 +55,6 @@ private:
     const DataFactory* _factory;
 };
 
-inline SimpleDataPool::SimpleDataPool(const DataFactory* factory)
-    : _capacity(0)
-    , _size(0)
-    , _ncreated(0)
-    , _pool(NULL)
-    , _factory(factory) {
-}
-
-inline SimpleDataPool::~SimpleDataPool() {
-    Reset(NULL);
-}
-
-inline void SimpleDataPool::Reset(const DataFactory* factory) {
-    unsigned saved_size = 0;
-    void** saved_pool = NULL;
-    const DataFactory* saved_factory = NULL;
-    {
-        BAIDU_SCOPED_LOCK(_mutex);
-        saved_size = _size;
-        saved_pool = _pool;
-        saved_factory = _factory;
-        _capacity = 0;
-        _size = 0;
-        _ncreated.store(0, butil::memory_order_relaxed);
-        _pool = NULL;
-        _factory = factory;
-    }
-    if (saved_pool) {
-        if (saved_factory) {
-            for (unsigned i = 0; i < saved_size; ++i) {
-                saved_factory->DestroyData(saved_pool[i]);
-            }
-        }
-        free(saved_pool);
-    }
-}
-
-inline void SimpleDataPool::Reserve(unsigned n) {
-    if (_capacity >= n) {
-        return;
-    }
-    BAIDU_SCOPED_LOCK(_mutex);
-    if (_capacity >= n) {
-        return;
-    }
-    // Resize.
-    const unsigned new_cap = std::max(_capacity * 3 / 2, n);
-    void** new_pool = (void**)malloc(new_cap * sizeof(void*));
-    if (NULL == new_pool) {
-        return;
-    }
-    if (_pool) {
-        memcpy(new_pool, _pool, _capacity * sizeof(void*));
-        free(_pool);
-    }
-    unsigned i = _capacity;
-    _capacity = new_cap;
-    _pool = new_pool;
-
-    for (; i < n; ++i) {
-        void* data = _factory->CreateData();
-        if (data == NULL) {
-            break;
-        }
-        _ncreated.fetch_add(1,  butil::memory_order_relaxed);
-        _pool[_size++] = data;
-    }
-}
-
-inline void* SimpleDataPool::Borrow() {
-    if (_size) {
-        BAIDU_SCOPED_LOCK(_mutex);
-        if (_size) {
-            return _pool[--_size];
-        }
-    }
-    void* data = _factory->CreateData();
-    if (data) {
-        _ncreated.fetch_add(1,  butil::memory_order_relaxed);
-    }
-    return data;
-}
-
-inline void SimpleDataPool::Return(void* data) {
-    if (data == NULL) {
-        return;
-    }
-    std::unique_lock<butil::Mutex> mu(_mutex);
-    if (_capacity == _size) {
-        const unsigned new_cap = (_capacity <= 1 ? 128 : (_capacity * 3 / 2));
-        void** new_pool = (void**)malloc(new_cap * sizeof(void*));
-        if (NULL == new_pool) {
-            mu.unlock();
-            return _factory->DestroyData(data);
-        }
-        if (_pool) {
-            memcpy(new_pool, _pool, _capacity * sizeof(void*));
-            free(_pool);
-        }
-        _capacity = new_cap;
-        _pool = new_pool;
-    }
-    _pool[_size++] = data;
-}
-
-inline SimpleDataPool::Stat SimpleDataPool::stat() const {
-    Stat s = { _size, _ncreated.load(butil::memory_order_relaxed) };
-    return s;
-}
-
 } // namespace brpc
 
-
 #endif  // BRPC_SIMPLE_DATA_POOL_H


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@brpc.apache.org
For additional commands, e-mail: dev-help@brpc.apache.org