11
11
#define environ (*_NSGetEnviron())
12
12
#endif
13
13
14
+ #ifdef OS_UNIX
15
+ #include <sys/file.h>
16
+ #endif
17
+
18
+ static FILE* s_fp = NULL;
19
+
14
20
main_ctx_t g_main_ctx;
15
21
16
22
static void init_arg_kv(int maxsize) {
@@ -73,7 +79,7 @@ int main_ctx_init(int argc, char** argv) {
73
79
get_executable_path(argv[0], MAX_PATH);
74
80
}
75
81
76
- get_run_dir(g_main_ctx.run_dir, sizeof(g_main_ctx.run_dir));
82
+ if(!hv_exists(g_main_ctx.run_dir)) get_run_dir(g_main_ctx.run_dir, sizeof(g_main_ctx.run_dir));
77
83
//printf("run_dir=%s\n", g_main_ctx.run_dir);
78
84
strncpy(g_main_ctx.program_name, hv_basename(argv[0]), sizeof(g_main_ctx.program_name));
79
85
#ifdef OS_WIN
@@ -89,21 +95,36 @@ int main_ctx_init(int argc, char** argv) {
89
95
snprintf(g_main_ctx.pidfile, sizeof(g_main_ctx.pidfile), "%s/logs/%s.pid", g_main_ctx.run_dir, g_main_ctx.program_name);
90
96
snprintf(g_main_ctx.logfile, sizeof(g_main_ctx.logfile), "%s/logs/%s.log", g_main_ctx.run_dir, g_main_ctx.program_name);
91
97
hlog_set_file(g_main_ctx.logfile);
92
-
98
+ #ifdef OS_WIN
99
+ // Only Windows does not allow deleting occupied files
100
+ remove(g_main_ctx.pidfile);
101
+ #endif
93
102
g_main_ctx.pid = getpid();
94
103
g_main_ctx.oldpid = getpid_from_pidfile();
95
104
#ifdef OS_UNIX
96
- if (kill(g_main_ctx.oldpid, 0) == -1 && errno == ESRCH) {
97
- g_main_ctx.oldpid = -1;
105
+ s_fp = fopen(g_main_ctx.pidfile, "a");
106
+ if(s_fp != NULL) {
107
+ if(flock(fileno(s_fp), LOCK_EX | LOCK_NB) == 0) {
108
+ // The lock is successful, indicating that oldpid has ended
109
+ g_main_ctx.oldpid = -1;
110
+ flock(fileno(s_fp), LOCK_UN);
111
+ }
112
+ fclose(s_fp);
113
+ s_fp = NULL;
98
114
}
99
- #else
100
- HANDLE hproc = OpenProcess(PROCESS_TERMINATE, FALSE, g_main_ctx.oldpid);
101
- if (hproc == NULL) {
115
+ if (kill(g_main_ctx.oldpid, 0) == -1 && errno == ESRCH) {
102
116
g_main_ctx.oldpid = -1;
103
117
}
104
- else {
118
+ #endif
119
+
120
+ #ifdef OS_WIN
121
+ DWORD exitCode = 0;
122
+ const HANDLE hproc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, g_main_ctx.oldpid);
123
+ if (hproc) {
124
+ GetExitCodeProcess(hproc, &exitCode);
105
125
CloseHandle(hproc);
106
126
}
127
+ if(exitCode != STILL_ACTIVE) g_main_ctx.oldpid = -1;
107
128
#endif
108
129
109
130
// save arg
@@ -429,22 +450,38 @@ void setproctitle(const char* fmt, ...) {
429
450
#endif
430
451
431
452
int create_pidfile() {
432
- FILE* fp = fopen(g_main_ctx.pidfile, "w ");
433
- if (fp == NULL) {
453
+ s_fp = fopen(g_main_ctx.pidfile, "a ");
454
+ if (s_fp == NULL) {
434
455
hloge("fopen('%s') error: %d", g_main_ctx.pidfile, errno);
435
456
return -1;
436
457
}
437
-
458
+ #ifdef OS_UNIX
459
+ if (flock(fileno(s_fp), LOCK_EX | LOCK_NB) < 0) {
460
+ hloge("flock('%s') error: %d", g_main_ctx.pidfile, errno);
461
+ fclose(s_fp);
462
+ s_fp = NULL;
463
+ return -1;
464
+ }
465
+ ftruncate(fileno(s_fp), 0);
466
+ #else
467
+ chsize(fileno(s_fp), 0);
468
+ #endif
438
469
g_main_ctx.pid = hv_getpid();
439
- fprintf(fp , "%d\n", (int)g_main_ctx.pid);
440
- fclose(fp );
470
+ fprintf(s_fp , "%d\n", (int)g_main_ctx.pid);
471
+ fflush(s_fp );
441
472
hlogi("create_pidfile('%s') pid=%d", g_main_ctx.pidfile, g_main_ctx.pid);
442
473
atexit(delete_pidfile);
443
474
return 0;
444
475
}
445
476
446
477
void delete_pidfile(void) {
478
+ if(s_fp == NULL) return;
447
479
hlogi("delete_pidfile('%s') pid=%d", g_main_ctx.pidfile, g_main_ctx.pid);
480
+ #ifdef OS_UNIX
481
+ flock(fileno(s_fp), LOCK_UN);
482
+ #endif
483
+ fclose(s_fp);
484
+ s_fp = NULL;
448
485
remove(g_main_ctx.pidfile);
449
486
}
450
487
@@ -637,7 +674,7 @@ void signal_handle(const char* signal) {
637
674
if (g_main_ctx.oldpid > 0) {
638
675
printf("%s start/running, pid=%d\n", g_main_ctx.program_name, g_main_ctx.oldpid);
639
676
} else {
640
- printf("%s stop/waiting \n", g_main_ctx.program_name);
677
+ printf("%s is already stopped \n", g_main_ctx.program_name);
641
678
}
642
679
exit(0);
643
680
} else if (strcmp(signal, "reload") == 0) {
@@ -648,8 +685,10 @@ void signal_handle(const char* signal) {
648
685
#else
649
686
SetEvent(s_hEventReload);
650
687
#endif
688
+ hv_sleep(1);
689
+ } else {
690
+ printf_fn("%s is already stopped\n", g_main_ctx.program_name);
651
691
}
652
- hv_sleep(1);
653
692
exit(0);
654
693
} else {
655
694
printf("Invalid signal: '%s'\n", signal);
0 commit comments