浏览代码

feat: 调整aFunlang的信号系统

SongZihuan 3 年之前
父节点
当前提交
cd957a429b
共有 13 个文件被更改,包括 113 次插入34 次删除
  1. 1 0
      include/core/aFunCore.h
  2. 10 1
      include/core/core_init.h
  3. 20 0
      include/core/sig.h
  4. 2 0
      include/runtime/aFunlang.h
  5. 1 17
      src/core/__sig.h
  6. 9 0
      src/core/core_init.c
  7. 3 3
      src/core/run.c
  8. 8 4
      src/core/sig.c
  9. 15 3
      src/main.c
  10. 13 5
      src/main_signal.c
  11. 8 1
      src/main_signal.h
  12. 17 0
      src/runtime/aFunlang.c
  13. 6 0
      test/src/run_code.c

+ 1 - 0
include/core/aFunCore.h

@@ -11,6 +11,7 @@
 #include "runtime_error.h"
 
 #include "core_init.h"
+#include "sig.h"
 #include "run.h"
 #include "code.h"
 #include "bytecode.h"

+ 10 - 1
include/core/core_init.h

@@ -1,8 +1,9 @@
 #ifndef AFUN_INIT_H
 #define AFUN_INIT_H
 #include "aFunCoreExport.h"
-#include "stdbool.h"
 #include <setjmp.h>
+#include "macro.h"
+#include "sig.h"
 #include "tool.h"
 
 typedef struct aFunCoreInitInfo aFunCoreInitInfo;
@@ -13,7 +14,15 @@ struct aFunCoreInitInfo {
     LogLevel level;
 };
 
+typedef struct aFunRunInfo aFunRunInfo;
+struct aFunRunInfo {
+    struct af_SignalInfo si;
+};
+
 AFUN_CORE_EXPORT extern Logger *aFunCoreLogger;
 AFUN_CORE_EXPORT bool aFunCoreInit(aFunCoreInitInfo *info);
 
+AFUN_CORE_EXPORT void defineRunEnvCore(aFunRunInfo *run_env);
+AFUN_CORE_EXPORT void undefRunEnvCore(aFunRunInfo *run_env);
+
 #endif //AFUN_INIT_H

+ 20 - 0
include/core/sig.h

@@ -0,0 +1,20 @@
+#ifndef AFUN_SIG_H
+#define AFUN_SIG_H
+
+#include "aFunCoreExport.h"
+
+struct af_SignalInfo {
+    void *sig_int;
+    void *sig_term;
+#if (defined SIGUSR1 && defined SIGUSR2)
+    void *sig_u1;
+    void *sig_u2;
+#endif
+};
+typedef struct af_SignalInfo af_SignalInfo;
+
+AFUN_CORE_EXPORT void aFunSignalInit(af_SignalInfo *sig_info);
+AFUN_CORE_EXPORT void aFunSignalRecover(af_SignalInfo *sig_info);
+AFUN_CORE_EXPORT bool aFunGetSignal(int signum);
+
+#endif //AFUN_SIG_H

+ 2 - 0
include/runtime/aFunlang.h

@@ -13,6 +13,8 @@ struct aFunInitInfo {
 };
 
 AFUN_LANG_EXPORT bool aFunInit(aFunInitInfo *info);
+AFUN_LANG_EXPORT void defineRunEnv(aFunRunInfo *run_env);
+AFUN_LANG_EXPORT void undefRunEnv(aFunRunInfo *run_env);
 
 AFUN_LANG_EXPORT af_Environment *creatAFunEnvironment(int argc, char **argv);
 AFUN_LANG_EXPORT void destructAFunEnvironment(af_Environment *env);

+ 1 - 17
src/core/__sig.h

@@ -1,21 +1,5 @@
 #ifndef AFUN___SIG_H_
 #define AFUN___SIG_H_
 #include <signal.h>
-#include "aFunCoreExport.h"
-
-struct af_SignalInfo {
-    void *sig_int;
-    void *sig_term;
-#if (defined SIGUSR1 && defined SIGUSR2)
-    void *sig_u1;
-    void *sig_u2;
-#endif
-};
-
-typedef struct af_SignalInfo af_SignalInfo;
-
-AFUN_CORE_NO_EXPORT void aFunSignalInit(af_SignalInfo *sig_info);
-AFUN_CORE_NO_EXPORT void aFunSignalRecover(af_SignalInfo *sig_info);
-AFUN_CORE_NO_EXPORT bool aFunGetSignal(int signum);
-
+#include "sig.h"
 #endif //AFUN___SIG_H_

+ 9 - 0
src/core/core_init.c

@@ -76,3 +76,12 @@ bool aFunCoreInit(aFunCoreInitInfo *info) {
     writeDebugLog(aFunCoreLogger, "aFunCore init success");
     return true;
 }
+
+void defineRunEnvCore(aFunRunInfo *run_env) {
+    memset(&run_env->si, 0, sizeof(af_SignalInfo));
+    aFunSignalInit(&run_env->si);
+}
+
+void undefRunEnvCore(aFunRunInfo *run_env) {
+    aFunSignalRecover(&run_env->si);
+}

+ 3 - 3
src/core/run.c

@@ -366,8 +366,8 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
         return false;
 
     bool re = true;
-    af_SignalInfo si;
-    aFunSignalInit(&si);
+    aFunRunInfo ri;
+    defineRunEnvCore(&ri);
 
     /*
      * 问题: 如何确保循环跳出之前, top-Activity已经被pop。(即执行释放)
@@ -502,7 +502,7 @@ bool iterCode(af_Code *code, int mode, af_Environment *env){
     }
 
 RETURN:
-    aFunSignalRecover(&si);
+    undefRunEnvCore(&ri);
     env->in_run = false;
     return re;
 }

+ 8 - 4
src/core/sig.c

@@ -66,21 +66,25 @@ bool aFunGetSignal(int signum) {
 void aFunSignalInit(af_SignalInfo *sig_info) {
     writeDebugLog(aFunCoreLogger, "Signal setting");
 
-    sig_int = 0;
     sig_info->sig_int = signal(SIGINT, aFunSigFunc);
+    if (aFunSigFunc != sig_info->sig_int)
+        sig_int = 0;
     assertWarningLog(sig_info->sig_int != SIG_ERR, aFunCoreLogger, "SIGINT setting fail");
 
-    sig_term = 0;
     sig_info->sig_term = signal(SIGTERM, aFunSigFunc);
+    if (aFunSigFunc != sig_info->sig_term)
+        sig_term = 0;
     assertWarningLog(sig_info->sig_term != SIG_ERR, aFunCoreLogger, "SIGTERM setting fail");
 
 #if (defined SIGUSR1 && defined SIGUSR2)
-    sig_u1 = 0;
     sig_info->sig_u1 = signal(SIGUSR1, aFunSigFunc);
+    if (aFunSigFunc != sig_info->sig_u1)
+        sig_u1 = 0;
     assertWarningLog(sig_info->sig_u1 != SIG_ERR, aFunCoreLogger, "SIGUSR1 setting fail");
 
-    sig_u2 = 0;
     sig_info->sig_u2 = signal(SIGUSR2, aFunSigFunc);
+    if (aFunSigFunc != sig_info->sig_u2)
+        sig_u2 = 0;
     assertWarningLog(sig_info->sig_u2 != SIG_ERR, aFunCoreLogger, "SIGUSR2 setting fail");
 #endif
 }

+ 15 - 3
src/main.c

@@ -46,6 +46,8 @@ char *base_path = NULL;
 static Logger aFunlangLogger_;
 Logger *aFunlangLogger = &aFunlangLogger_;
 
+#define CHECK_SIGNAL() do{if (getSignal()){writeErrorLog(aFunlangLogger, "SIGINT");return EXIT_FAILURE;}}while(0)
+
 void freeBaseName(void) {
     free(base_path);
 }
@@ -79,8 +81,6 @@ INIT_ERROR:
     aFunlangLogger->buf = &main_buf;
     writeDebugLog(aFunlangLogger, "aFunlang-exe init success");
 
-    signalInit();
-
     int exit_code = EXIT_SUCCESS;
     ff_FFlags *ff = ff_initFFlags(argc, argv, true, false, stderr, aFunlang_exe);
     if (ff == NULL)
@@ -175,6 +175,8 @@ static int mainRun(ff_FFlags *ff) {
     char **argv = NULL;
     int argc = ff_get_process_argv(&argv, ff);
     af_Environment *env;
+    aFunRunInfo ri = {0};
+    defineRunEnv(&ri);
 
     if (argc == 0) {
         /* 进入命令行模式 */
@@ -195,6 +197,7 @@ static int mainRun(ff_FFlags *ff) {
         destructAFunEnvironment(env);
     }
 
+    undefRunEnv(&ri);
     if (exit_code != 0)
         writeErrorLog(aFunlangLogger, "aFun exit code: %d", exit_code);
     else
@@ -278,7 +281,12 @@ static int mainCL(ff_FFlags *ff) {
     for (int i = 0; ff_getopt_wild_after(&text, ff); i++)
         argv[i] = text;
 
+    CHECK_SIGNAL();
+
     af_Environment *env = creatAFunEnvironment(argc, argv);
+    aFunRunInfo ri = {0};
+    defineRunEnv(&ri);  // 由aFunCore提前接管
+
     if (rl != NULL)
         exit_code = runCodeFromRunList(rl, NULL, save_aub, env);
 
@@ -300,6 +308,7 @@ static int mainCL(ff_FFlags *ff) {
         writeInfoLog(aFunlangLogger, "aFun exit code: %d", exit_code);
     printf_stdout(0, "aFun %s: %d\n", HT_aFunGetText(exit_code_n, "exit code"), exit_code);
 
+    undefRunEnv(&ri);
     destructAFunEnvironment(env);
     freeAllRunList(rl);
     free(argv);
@@ -362,6 +371,7 @@ out:
             goto error;
         }
 
+        CHECK_SIGNAL();  // 检查信号
         return buildFileOutput(out_put, in, force);
     } else if (path != NULL) {
         int exit_code = 0;
@@ -371,8 +381,10 @@ out:
     }
 
     int exit_code = 0;
-    while (ff_getopt_wild(&text, ff) && exit_code == 0)
+    while (ff_getopt_wild(&text, ff) && exit_code == 0) {
+        CHECK_SIGNAL();  // 检查信号
         exit_code = buildFileToSelf(text, force);
+    }
     return exit_code;
 
 error:

+ 13 - 5
src/main_signal.c

@@ -1,6 +1,7 @@
 #include "aFun.h"
 #include "signal.h"
 #include "main.h"
+#include "main_signal.h"
 
 static volatile sig_atomic_t sig = 0;  // SIGINT (Windows & *nix)
 
@@ -12,8 +13,7 @@ static void sigFunc(int signum) {
 }
 
 bool getSignal(void) {
-    int re = sig;
-    if (re == 1) {
+    if (sig == 1 || aFunGetSignal(SIGINT) || aFunGetSignal(SIGTERM)) {
         sig = 0;
         signal(SIGINT, sigFunc);
         signal(SIGTERM, sigFunc);
@@ -22,10 +22,18 @@ bool getSignal(void) {
     return false;
 }
 
-void signalInit(void) {
+void signalInit(SignalInfo *si) {
     writeDebugLog(aFunlangLogger, "aFunlang signal init");
     sig = 0;
-    signal(SIGINT, sigFunc);
-    signal(SIGTERM, sigFunc);
+    si->sig_int = signal(SIGINT, sigFunc);
+    si->sig_term = signal(SIGTERM, sigFunc);
 }
 
+void signalRecover(SignalInfo *si) {
+    writeDebugLog(aFunlangLogger, "aFunlang signal init");
+    sig = 0;
+    if (si->sig_int != SIG_ERR)
+        signal(SIGINT, si->sig_int);
+    if (si->sig_term != SIG_ERR)
+        signal(SIGTERM, si->sig_term);
+}

+ 8 - 1
src/main_signal.h

@@ -2,7 +2,14 @@
 #define AFUN_MAIN_SIGNAL_H
 #include "main.h"
 
+typedef struct SignalInfo SignalInfo;
+struct SignalInfo {
+    void *sig_int;
+    void *sig_term;
+};
+
 bool getSignal(void);
-void signalInit(void);
+void signalInit(SignalInfo *si);
+void signalRecover(SignalInfo *si);
 
 #endif //AFUN_MAIN_SIGNAL_H

+ 17 - 0
src/runtime/aFunlang.c

@@ -28,6 +28,23 @@ bool aFunInit(aFunInitInfo *info) {
     return aFunInit_mark;
 }
 
+/*
+ * 函数名: defineRunEnv
+ * 目标: 运行前的初始化
+ */
+void defineRunEnv(aFunRunInfo *run_env) {
+    defineRunEnvCore(run_env);
+}
+
+/*
+ * 函数名: undefRunEnv
+ * 目标: 取消运行前的初始哈
+ */
+void undefRunEnv(aFunRunInfo *run_env) {
+    undefRunEnvCore(run_env);
+}
+
+
 af_Environment *creatAFunEnvironment(int argc, char **argv){
     if (!aFunInit_mark)
         return NULL;

+ 6 - 0
test/src/run_code.c

@@ -413,6 +413,9 @@ INIT_ERROR:
 
 
     af_Environment *env = creatAFunEnvironment(0, NULL);
+    aFunRunInfo ri = {0};
+    defineRunEnv(&ri);
+
     if(!pushLiteralRegex("data.*", "func", true, env)) {
         fprintf(stderr, "pushLiteralRegex Error\n");
         goto RETURN_1;
@@ -1297,6 +1300,7 @@ INIT_ERROR:
     printf("freeEnvironment:\n");
     destructAFunEnvironment(env);
 
+    undefRunEnv(&ri);
     printf("Exit at 0.");
 #ifndef IN_CTEST
     getc(stdin);
@@ -1304,6 +1308,7 @@ INIT_ERROR:
     return 0;
 
 RETURN_1:
+    undefRunEnv(&ri);
     printf("Exit at 1.");
 #ifndef IN_CTEST
     getc(stdin);
@@ -1311,6 +1316,7 @@ RETURN_1:
     return 1;
 
 RETURN_2:
+    undefRunEnv(&ri);
     printf("Exit at 2.");
 #ifndef IN_CTEST
     getc(stdin);