Sfoglia il codice sorgente

refactor & feat: Var和Value添加互斥锁

SongZihuan 3 anni fa
parent
commit
12e9dafe32

+ 3 - 0
include/core/msg.h

@@ -105,6 +105,9 @@ namespace aFuncore {
 
         template <typename Callable, typename...T>
         void forEach(Callable func, T...arg);
+
+        template <typename Callable, typename...T>
+        void forEachLock(Callable func, T...arg);
     private:
         std::mutex lock;
     };

+ 7 - 0
include/core/msg.template.h

@@ -32,6 +32,13 @@ namespace aFuncore {
             mutex.lock();
         }
     }
+
+    template<typename Callable, typename... T>
+    void InterMessage::forEachLock(Callable func, T... arg) {
+        std::unique_lock<std::mutex> mutex{lock};
+        for (auto &msg : stream)
+            func(msg.second, arg...);
+    }
 }
 
 #endif //AFUN_MSG_TEMPLATE_H

+ 5 - 1
include/core/value.h

@@ -1,8 +1,9 @@
 #ifndef AFUN_VALUE_H
 #define AFUN_VALUE_H
+#include <list>
+#include <mutex>
 #include "aFuntool.h"
 #include "aFunCoreExport.h"
-#include "list"
 #include "gc.h"
 #include "code.h"
 #include "inter.h"
@@ -16,6 +17,9 @@ namespace aFuncore {
         Object(std::string type_, Inter &inter);
         Object(std::string type_, Environment &env_);
         ~Object() override = default;
+
+    protected:
+        std::mutex lock;
     };
 
     class AFUN_CORE_EXPORT Function : public virtual Object {

+ 17 - 1
include/core/var.h

@@ -2,6 +2,7 @@
 #define AFUN_VAR_H
 #include <list>
 #include <unordered_map>
+#include <mutex>
 #include "aFuntool.h"
 #include "aFunCoreExport.h"
 #include "gc.h"
@@ -21,6 +22,9 @@ namespace aFuncore {
         [[nodiscard]] inline virtual Object *getData();
         virtual void inline setData(Object *data_);
 
+    protected:
+        std::mutex lock;
+
     private:
         Object *data;
     };
@@ -43,7 +47,10 @@ namespace aFuncore {
         template <typename Callable,typename...T>
         void forEach(Callable func, T...arg);
 
-        [[nodiscard]] inline size_t getCount() const;
+        template <typename Callable,typename...T>
+        void forEachLock(Callable func, T...arg);
+
+        [[nodiscard]] inline size_t getCount();
         [[nodiscard]] virtual Var *findVar(const std::string &name);
         virtual VarOperationFlat defineVar(const std::string &name, Object *data);
         virtual VarOperationFlat defineVar(const std::string &name, Var *data);
@@ -54,6 +61,9 @@ namespace aFuncore {
 
         static const size_t VAR_HASH_SIZE = 100;  // 环境变量哈希表大小
 
+    protected:
+        std::mutex lock;
+
     private:
         std::unordered_map<std::string, Var *> var;
     };
@@ -90,6 +100,9 @@ namespace aFuncore {
         template <typename Callable,typename...T>
         void forEach(Callable func, T...arg);
 
+        template <typename Callable,typename...T>
+        void forEachLock(Callable func, T...arg);
+
         [[nodiscard]] virtual Var *findVar(const std::string &name);
         virtual bool defineVar(const std::string &name, Object *data);
         virtual bool defineVar(const std::string &name, Var *data);
@@ -97,6 +110,9 @@ namespace aFuncore {
         virtual bool delVar(const std::string &name);
         [[nodiscard]] inline Object *findObject(const std::string &name);
 
+    protected:
+        std::mutex lock;
+
     private:
         std::list<VarSpace *> varspace;
     };

+ 5 - 1
include/core/var.inline.h

@@ -4,14 +4,17 @@
 
 namespace aFuncore {
     inline Object *Var::getData() {
+        std::unique_lock<std::mutex> mutex{lock};
         return data;
     }
 
     inline void Var::setData(Object *data_) {
+        std::unique_lock<std::mutex> mutex{lock};
         data = data_;
     }
 
-    inline size_t VarSpace::getCount() const {
+    inline size_t VarSpace::getCount() {
+        std::unique_lock<std::mutex> mutex{lock};
         return var.size();
     }
 
@@ -41,6 +44,7 @@ namespace aFuncore {
     }
 
     inline void VarList::push(VarSpace *varspace_) {
+        std::unique_lock<std::mutex> mutex{lock};
         varspace.push_front(varspace_);
     }
 

+ 25 - 5
include/core/var.template.h

@@ -2,16 +2,36 @@
 #define AFUN_VAR_TEMPLATE_H
 
 namespace aFuncore {
-    template <typename Callable,typename...T>
+    template <typename Callable, typename...T>
     void VarSpace::forEach(Callable func, T...arg) {
-        for (int i = 0; i < VAR_HASH_SIZE; i++) {
-            for (auto &tmp : var)
-                func(tmp.second, arg...);
+        std::unique_lock<std::mutex> mutex{lock};
+        for (auto &tmp : var) {
+            mutex.unlock();
+            func(tmp.second, arg...);
+            mutex.lock();
         }
     }
 
-    template <typename Callable,typename...T>
+    template <typename Callable, typename...T>
+    void VarSpace::forEachLock(Callable func, T...arg) {
+        std::unique_lock<std::mutex> mutex{lock};
+        for (auto &tmp : var)
+            func(tmp.second, arg...);
+    }
+
+    template <typename Callable, typename...T>
     void VarList::forEach(Callable func, T...arg) {
+        std::unique_lock<std::mutex> mutex{lock};
+        for (auto &vs : varspace) {
+            mutex.unlock();
+            func(vs, arg...);
+            mutex.lock();
+        }
+    }
+
+    template <typename Callable, typename...T>
+    void VarList::forEachLock(Callable func, T...arg) {
+        std::unique_lock<std::mutex> mutex{lock};
         for (auto &vs : varspace)
             func(vs, arg...);
     }

+ 36 - 6
src/core/var.cpp

@@ -28,6 +28,7 @@ namespace aFuncore {
      * @return
      */
     Var *VarSpace::findVar(const std::string &name){
+        std::unique_lock<std::mutex> mutex{lock};
         auto v = var.find(name);
         if (v == var.end())
             return nullptr;
@@ -41,6 +42,7 @@ namespace aFuncore {
      * @return
      */
     VarSpace::VarOperationFlat VarSpace::defineVar(const std::string &name, Object *data) {
+        std::unique_lock<std::mutex> mutex{lock};
         if (var.find(name) != var.end())
             return vof_redefine_var;
         var.emplace(name, new Var(data, env));
@@ -54,6 +56,7 @@ namespace aFuncore {
      * @return
      */
     VarSpace::VarOperationFlat VarSpace::defineVar(const std::string &name, Var *data){
+        std::unique_lock<std::mutex> mutex{lock};
         if (var.find(name) != var.end())
             return vof_redefine_var;
         var.emplace(name, data);
@@ -67,6 +70,7 @@ namespace aFuncore {
      * @return
      */
     VarSpace::VarOperationFlat VarSpace::setVar(const std::string &name, Object *data){
+        std::unique_lock<std::mutex> mutex{lock};
         auto v = var.find(name);
         if (v == var.end())
             return vof_not_var;
@@ -80,6 +84,7 @@ namespace aFuncore {
      * @return
      */
     VarSpace::VarOperationFlat VarSpace::delVar(const std::string &name){
+        std::unique_lock<std::mutex> mutex{lock};
         auto v = var.find(name);
         if (v == var.end())
             return vof_not_var;
@@ -88,6 +93,7 @@ namespace aFuncore {
     }
     
     VarList::VarList(VarList *varlist){
+        std::unique_lock<std::mutex> mutex{lock};
         for (auto &t: varlist->varspace)
             this->varspace.push_back(t);
     }
@@ -150,9 +156,13 @@ namespace aFuncore {
      * @return
      */
     Var *VarList::findVar(const std::string &name){
+        std::unique_lock<std::mutex> mutex{lock};
         Var *ret = nullptr;
-        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == nullptr; tmp++)
+        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == nullptr; tmp++) {
+            mutex.unlock();
             ret = (*tmp)->findVar(name);
+            mutex.lock();
+        }
         return ret;
     }
     
@@ -165,9 +175,13 @@ namespace aFuncore {
      * @return
      */
     bool VarList::defineVar(const std::string &name, Object *data){
+        std::unique_lock<std::mutex> mutex{lock};
         VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
-        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
+        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++) {
+            mutex.unlock();
             ret = (*tmp)->defineVar(name, data);
+            mutex.lock();
+        }
         return ret == VarSpace::vof_success;
     }
     
@@ -180,9 +194,13 @@ namespace aFuncore {
      * @return
      */
     bool VarList::defineVar(const std::string &name, Var *data){
+        std::unique_lock<std::mutex> mutex{lock};
         VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
-        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
+        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++) {
+            mutex.unlock();
             ret = (*tmp)->defineVar(name, data);
+            mutex.lock();
+        }
         return ret == VarSpace::vof_success;
     }
     
@@ -195,9 +213,13 @@ namespace aFuncore {
      * @return
      */
     bool VarList::setVar(const std::string &name, Object *data){
+        std::unique_lock<std::mutex> mutex{lock};
         VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
-        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
+        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++) {
+            mutex.unlock();
             ret = (*tmp)->setVar(name, data);
+            mutex.lock();
+        }
         return ret == VarSpace::vof_success;
     }
     
@@ -209,15 +231,23 @@ namespace aFuncore {
      * @return
      */
     bool VarList::delVar(const std::string &name){
+        std::unique_lock<std::mutex> mutex{lock};
         VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
-        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
+        for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++) {
+            mutex.unlock();
             ret = (*tmp)->delVar(name);
+            mutex.lock();
+        }
         return ret == VarSpace::vof_success;
     }
     
     void VarList::connect(VarList *varlist){
-        for (auto &t: varlist->varspace)
+        std::unique_lock<std::mutex> mutex{lock};
+        for (auto &t: varlist->varspace) {
+            mutex.unlock();
             this->varspace.push_back(t);
+            mutex.lock();
+        }
     }
 
 }