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
printf_t printf_fn = printf ;
16
22
@@ -74,7 +80,7 @@ int main_ctx_init(int argc, char** argv) {
74
80
get_executable_path (argv [0 ], MAX_PATH );
75
81
}
76
82
77
- get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
83
+ if (! hv_exists ( g_main_ctx . run_dir )) get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
78
84
//printf("run_dir=%s\n", g_main_ctx.run_dir);
79
85
strncpy (g_main_ctx .program_name , hv_basename (argv [0 ]), sizeof (g_main_ctx .program_name ));
80
86
#ifdef OS_WIN
@@ -90,21 +96,36 @@ int main_ctx_init(int argc, char** argv) {
90
96
snprintf (g_main_ctx .pidfile , sizeof (g_main_ctx .pidfile ), "%s/logs/%s.pid" , g_main_ctx .run_dir , g_main_ctx .program_name );
91
97
snprintf (g_main_ctx .logfile , sizeof (g_main_ctx .logfile ), "%s/logs/%s.log" , g_main_ctx .run_dir , g_main_ctx .program_name );
92
98
hlog_set_file (g_main_ctx .logfile );
93
-
99
+ #ifdef OS_WIN
100
+ // Only Windows does not allow deleting occupied files
101
+ remove (g_main_ctx .pidfile );
102
+ #endif
94
103
g_main_ctx .pid = getpid ();
95
104
g_main_ctx .oldpid = getpid_from_pidfile ();
96
105
#ifdef OS_UNIX
97
- if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
98
- g_main_ctx .oldpid = -1 ;
106
+ s_fp = fopen (g_main_ctx .pidfile , "a" );
107
+ if (s_fp != NULL ) {
108
+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) == 0 ) {
109
+ // The lock is successful, indicating that oldpid has ended
110
+ g_main_ctx .oldpid = -1 ;
111
+ flock (fileno (s_fp ), LOCK_UN );
112
+ }
113
+ fclose (s_fp );
114
+ s_fp = NULL ;
99
115
}
100
- #else
101
- HANDLE hproc = OpenProcess (PROCESS_TERMINATE , FALSE, g_main_ctx .oldpid );
102
- if (hproc == NULL ) {
116
+ if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
103
117
g_main_ctx .oldpid = -1 ;
104
118
}
105
- else {
119
+ #endif
120
+
121
+ #ifdef OS_WIN
122
+ DWORD exitCode = 0 ;
123
+ const HANDLE hproc = OpenProcess (PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION , FALSE, g_main_ctx .oldpid );
124
+ if (hproc ) {
125
+ GetExitCodeProcess (hproc , & exitCode );
106
126
CloseHandle (hproc );
107
127
}
128
+ if (exitCode != STILL_ACTIVE ) g_main_ctx .oldpid = -1 ;
108
129
#endif
109
130
110
131
// save arg
@@ -430,22 +451,38 @@ void setproctitle(const char* fmt, ...) {
430
451
#endif
431
452
432
453
int create_pidfile () {
433
- FILE * fp = fopen (g_main_ctx .pidfile , "w " );
434
- if (fp == NULL ) {
454
+ s_fp = fopen (g_main_ctx .pidfile , "a " );
455
+ if (s_fp == NULL ) {
435
456
hloge ("fopen('%s') error: %d" , g_main_ctx .pidfile , errno );
436
457
return -1 ;
437
458
}
438
-
459
+ #ifdef OS_UNIX
460
+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) < 0 ) {
461
+ hloge ("flock('%s') error: %d" , g_main_ctx .pidfile , errno );
462
+ fclose (s_fp );
463
+ s_fp = NULL ;
464
+ return -1 ;
465
+ }
466
+ ftruncate (fileno (s_fp ), 0 );
467
+ #else
468
+ chsize (fileno (s_fp ), 0 );
469
+ #endif
439
470
g_main_ctx .pid = hv_getpid ();
440
- fprintf (fp , "%d\n" , (int )g_main_ctx .pid );
441
- fclose ( fp );
471
+ fprintf (s_fp , "%d\n" , (int )g_main_ctx .pid );
472
+ fflush ( s_fp );
442
473
hlogi ("create_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
443
474
atexit (delete_pidfile );
444
475
return 0 ;
445
476
}
446
477
447
478
void delete_pidfile (void ) {
479
+ if (s_fp == NULL ) return ;
448
480
hlogi ("delete_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
481
+ #ifdef OS_UNIX
482
+ flock (fileno (s_fp ), LOCK_UN );
483
+ #endif
484
+ fclose (s_fp );
485
+ s_fp = NULL ;
449
486
remove (g_main_ctx .pidfile );
450
487
}
451
488
0 commit comments