Pārlūkot izejas kodu

refactor & feat: 调整Exit机制

SongZihuan 3 gadi atpakaļ
vecāks
revīzija
a70cbc1c28
2 mainītis faili ar 67 papildinājumiem un 72 dzēšanām
  1. 5 4
      include/tool/tool-exit.h
  2. 62 68
      src/tool/exit.cpp

+ 5 - 4
include/tool/tool-exit.h

@@ -1,15 +1,16 @@
 #ifndef AFUN_EXIT_H
 #define AFUN_EXIT_H
+#include "aFunToolExport.h"
 
 namespace aFuntool {
     typedef void aFunExitFunc(void *);
 
     AFUN_TOOL_EXPORT void aFunExit(int exit_code) noexcept(false);
     [[noreturn]] AFUN_TOOL_EXPORT void aFunExitReal(int exit_code);
-    AFUN_TOOL_EXPORT int aFunTryExitPseudo();
-    AFUN_TOOL_EXPORT int aFunExitPseudo();
-    AFUN_TOOL_EXPORT int aFunAtExitTry(aFunExitFunc *func, void *data);
-    AFUN_TOOL_EXPORT int aFunAtExit(aFunExitFunc *func, void *data);
+    AFUN_TOOL_EXPORT bool aFunTryExitPseudo();
+    AFUN_TOOL_EXPORT void aFunExitPseudo();
+    AFUN_TOOL_EXPORT bool aFunAtExitTry(aFunExitFunc *func, void *data);
+    AFUN_TOOL_EXPORT void aFunAtExit(aFunExitFunc *func, void *data);
 }
 
 #endif //AFUN_EXIT_H

+ 62 - 68
src/tool/exit.cpp

@@ -1,27 +1,66 @@
-#include "tool.h"
+#include <mutex>
+#include <stack>
 #include "tool-exit.h"
 #include "tool-exception.h"
-#include "mutex"
 
 namespace aFuntool {
-    static const int exit_func_size = 1024;
-    static std::mutex exit_mutex;
-    struct ExitFuncData {
-        aFunExitFunc *func;
-        void *data;
-    } exit_func[exit_func_size];
+    class ExitManager {
+    public:
+        ExitManager() noexcept = default;
+
+        ~ExitManager() noexcept {
+            runExitData();
+        }
+
+        void runExitData() {
+            std::unique_lock<std::mutex> ul{exit_mutex};
+            while(!data.empty()) {
+                auto tmp = data.top();
+                tmp.func(tmp.data);
+                data.pop();
+            }
+        }
+
+        void pushExitData(aFunExitFunc *func, void *data_) {
+            std::unique_lock<std::mutex> ul{exit_mutex};
+            data.emplace(func, data_);
+        }
+
+        bool tryRunExitData() {
+            if (!exit_mutex.try_lock())
+                return false;
+            std::unique_lock<std::mutex> ul{exit_mutex, std::adopt_lock};
+            while(!data.empty()) {
+                auto tmp = data.top();
+                tmp.func(tmp.data);
+                data.pop();
+            }
+            return true;
+        }
+
+        bool tryPushExitData(aFunExitFunc *func, void *data_) {
+            if (!exit_mutex.try_lock())
+                return false;
+            std::unique_lock<std::mutex> ul{exit_mutex, std::adopt_lock};
+            data.emplace(func, data_);
+            return true;
+        }
+
+    private:
+        std::mutex exit_mutex;
+        struct ExitFuncData {
+            aFunExitFunc *func;
+            void *data;
+        };
+        std::stack<ExitFuncData> data;
+    } manager;
 
     /**
      * 退出程序
      * @param exit_code 退出代码
      */
     void aFunExit(int exit_code) noexcept(false) {
-        std::unique_lock<std::mutex> ul{exit_mutex};
-        for (int i = exit_func_size - 1; i >= 0; i--) {
-            if (exit_func[i].func != nullptr)
-                exit_func[i].func(exit_func[i].data);
-        }
-        ul.unlock();
+        manager.runExitData();
         throw Exit(exit_code);
     }
 
@@ -30,44 +69,22 @@ namespace aFuntool {
      * @param exit_code 退出代码
      */
     [[noreturn]] void aFunExitReal(int exit_code) {
-        std::unique_lock<std::mutex> ul{exit_mutex};
-        for (int i = exit_func_size - 1; i >= 0; i--) {
-            if (exit_func[i].func != nullptr)
-                exit_func[i].func(exit_func[i].data);
-        }
-        ul.unlock();
+        manager.runExitData();
         exit(exit_code);
     }
 
     /**
      * 尝试执行退出函数
      */
-    int aFunTryExitPseudo(){
-        if (exit_mutex.try_lock()) {
-            std::unique_lock<std::mutex> ul{exit_mutex, std::adopt_lock};
-            for (int i = exit_func_size - 1; i >= 0; i--) {
-                if (exit_func[i].func != nullptr)
-                    exit_func[i].func(exit_func[i].data);
-                exit_func[i].func = nullptr;
-                exit_func[i].data = nullptr;
-            }
-            return 1;
-        }
-        return 0;
+    bool aFunTryExitPseudo(){
+        return manager.tryRunExitData();
     }
 
     /**
      * 执行退出函数, 但不退出
      */
-    int aFunExitPseudo(){
-        std::unique_lock<std::mutex> ul{exit_mutex};
-        for (int i = exit_func_size - 1; i >= 0; i--) {
-            if (exit_func[i].func != nullptr)
-                exit_func[i].func(exit_func[i].data);
-            exit_func[i].func = nullptr;
-            exit_func[i].data = nullptr;
-        }
-        return 0;
+    void aFunExitPseudo(){
+        manager.runExitData();
     }
 
     /**
@@ -75,21 +92,8 @@ namespace aFuntool {
      * @param func 退出函数
      * @param data 参数
      */
-    int aFunAtExitTry(aFunExitFunc *func, void *data){
-        if (exit_mutex.try_lock()) {
-            std::unique_lock<std::mutex> ul{exit_mutex, std::adopt_lock};
-            struct ExitFuncData *tmp = exit_func;
-            int count = 0;
-            for (NULL; tmp->func != nullptr; tmp++, count++) {
-                if (count >= exit_func_size) {
-                    return -1;
-                }
-            }
-            tmp->func = func;
-            tmp->data = data;
-            return count;
-        }
-        return -1;
+    bool aFunAtExitTry(aFunExitFunc *func, void *data){
+        return manager.tryPushExitData(func, data);
     }
 
     /**
@@ -98,17 +102,7 @@ namespace aFuntool {
      * @param data 参数
      * @return
      */
-    int aFunAtExit(aFunExitFunc *func, void *data){
-        std::unique_lock<std::mutex> ul{exit_mutex};
-        struct ExitFuncData *tmp = exit_func;
-        int count = 0;
-        for (NULL; tmp->func != nullptr; tmp++, count++) {
-            if (count >= exit_func_size) {
-                return -1;
-            }
-        }
-        tmp->func = func;
-        tmp->data = data;
-        return count;
+    void aFunAtExit(aFunExitFunc *func, void *data){
+        manager.pushExitData(func, data);
     }
 }