Skip to content

Commit ee940a4

Browse files
committed
fix main_ctx_init misjudging oldpid running in special cases
support main_ctx_init custom set run_dir optimize signal_handle printf desc
1 parent 1e3dd55 commit ee940a4

File tree

1 file changed

+54
-15
lines changed

1 file changed

+54
-15
lines changed

base/hmain.c

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
#define environ (*_NSGetEnviron())
1212
#endif
1313

14+
#ifdef OS_UNIX
15+
#include <sys/file.h>
16+
#endif
17+
18+
static FILE* s_fp = NULL;
19+
1420
main_ctx_t g_main_ctx;
1521

1622
static void init_arg_kv(int maxsize) {
@@ -73,7 +79,7 @@ int main_ctx_init(int argc, char** argv) {
7379
get_executable_path(argv[0], MAX_PATH);
7480
}
7581

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));
7783
//printf("run_dir=%s\n", g_main_ctx.run_dir);
7884
strncpy(g_main_ctx.program_name, hv_basename(argv[0]), sizeof(g_main_ctx.program_name));
7985
#ifdef OS_WIN
@@ -89,21 +95,36 @@ int main_ctx_init(int argc, char** argv) {
8995
snprintf(g_main_ctx.pidfile, sizeof(g_main_ctx.pidfile), "%s/logs/%s.pid", g_main_ctx.run_dir, g_main_ctx.program_name);
9096
snprintf(g_main_ctx.logfile, sizeof(g_main_ctx.logfile), "%s/logs/%s.log", g_main_ctx.run_dir, g_main_ctx.program_name);
9197
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
93102
g_main_ctx.pid = getpid();
94103
g_main_ctx.oldpid = getpid_from_pidfile();
95104
#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;
98114
}
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) {
102116
g_main_ctx.oldpid = -1;
103117
}
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);
105125
CloseHandle(hproc);
106126
}
127+
if(exitCode != STILL_ACTIVE) g_main_ctx.oldpid = -1;
107128
#endif
108129

109130
// save arg
@@ -429,22 +450,38 @@ void setproctitle(const char* fmt, ...) {
429450
#endif
430451

431452
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) {
434455
hloge("fopen('%s') error: %d", g_main_ctx.pidfile, errno);
435456
return -1;
436457
}
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
438469
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);
441472
hlogi("create_pidfile('%s') pid=%d", g_main_ctx.pidfile, g_main_ctx.pid);
442473
atexit(delete_pidfile);
443474
return 0;
444475
}
445476

446477
void delete_pidfile(void) {
478+
if(s_fp == NULL) return;
447479
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;
448485
remove(g_main_ctx.pidfile);
449486
}
450487

@@ -637,7 +674,7 @@ void signal_handle(const char* signal) {
637674
if (g_main_ctx.oldpid > 0) {
638675
printf("%s start/running, pid=%d\n", g_main_ctx.program_name, g_main_ctx.oldpid);
639676
} else {
640-
printf("%s stop/waiting\n", g_main_ctx.program_name);
677+
printf("%s is already stopped\n", g_main_ctx.program_name);
641678
}
642679
exit(0);
643680
} else if (strcmp(signal, "reload") == 0) {
@@ -648,8 +685,10 @@ void signal_handle(const char* signal) {
648685
#else
649686
SetEvent(s_hEventReload);
650687
#endif
688+
hv_sleep(1);
689+
} else {
690+
printf_fn("%s is already stopped\n", g_main_ctx.program_name);
651691
}
652-
hv_sleep(1);
653692
exit(0);
654693
} else {
655694
printf("Invalid signal: '%s'\n", signal);

0 commit comments

Comments
 (0)