15
15
#define MIMETYPE_JSON " application/json; charset=utf-8"
16
16
17
17
// auto generated files (see README.md for details)
18
- #include " index.html.gz.hpp "
19
- #include " loading.html.hpp "
18
+ #include < signal.h >
19
+ #include < unistd.h >
20
20
21
21
#include < atomic>
22
22
#include < chrono>
23
+ #include < cinttypes>
23
24
#include < condition_variable>
24
25
#include < cstddef>
25
- #include < cinttypes>
26
26
#include < deque>
27
27
#include < memory>
28
28
#include < mutex>
29
- #include < signal.h>
30
29
#include < thread>
31
30
#include < unordered_map>
32
31
#include < unordered_set>
33
32
33
+ #include " index.html.gz.hpp"
34
+ #include " loading.html.hpp"
35
+
36
+ #ifdef _WIN32
37
+ #include < process.h>
38
+ #define getpid _getpid
39
+ #endif
40
+
34
41
using json = nlohmann::ordered_json;
35
42
36
43
constexpr int HTTP_POLLING_SECONDS = 1 ;
@@ -3691,6 +3698,77 @@ inline void signal_handler(int signal) {
3691
3698
shutdown_handler (signal);
3692
3699
}
3693
3700
3701
+ static bool check_pid_alive (const pid_t pid) {
3702
+ if (pid <= 0 ) {
3703
+ return false ;
3704
+ }
3705
+
3706
+ // Process is alive or exists but is inaccessible
3707
+ if (kill (pid, 0 ) == 0 || errno == EPERM) {
3708
+ return true ; // Process is alive
3709
+ }
3710
+
3711
+ return false ; // Process does not exist or other error
3712
+ }
3713
+
3714
+ class PidFile {
3715
+ public:
3716
+ FILE * file = nullptr ;
3717
+ std::string fname;
3718
+ bool rm = false ;
3719
+
3720
+ FILE * open (const std::string & filename, const char * mode, const bool r = false ) {
3721
+ file = ggml_fopen (filename.c_str (), mode);
3722
+ fname = filename;
3723
+ rm = r;
3724
+
3725
+ return file;
3726
+ }
3727
+
3728
+ void close () {
3729
+ fclose (file);
3730
+ file = nullptr ;
3731
+
3732
+ if (rm) {
3733
+ // Remove stale pidfile
3734
+ unlink (fname.c_str ());
3735
+ }
3736
+ }
3737
+
3738
+ ~PidFile () {
3739
+ if (file) {
3740
+ close ();
3741
+ }
3742
+ }
3743
+ };
3744
+
3745
+ static bool is_old_pid_alive (const std::string & filename) {
3746
+ pid_t oldpid = 0 ;
3747
+ PidFile f;
3748
+ if (f.open (filename, " r" )) {
3749
+ if (fscanf (f.file , " %d" , &oldpid) == 1 ) {
3750
+ if (check_pid_alive (oldpid)) {
3751
+ LOG_ERR (" Process already running with PID %d\n " , oldpid);
3752
+ return true ;
3753
+ }
3754
+ }
3755
+ }
3756
+
3757
+ return false ;
3758
+ }
3759
+
3760
+ static int create_pidfile (const std::string & pidfile, PidFile & f) {
3761
+ if (!f.open (pidfile.c_str (), " w" , true )) {
3762
+ LOG_ERR (" Unable to open pidfile %s: %s\n " , pidfile.c_str (), strerror (errno));
3763
+ return -1 ;
3764
+ }
3765
+
3766
+ fprintf (f.file , " %d\n " , getpid ());
3767
+ fflush (f.file );
3768
+
3769
+ return 0 ;
3770
+ }
3771
+
3694
3772
int main (int argc, char ** argv) {
3695
3773
// own arguments required by this example
3696
3774
common_params params;
@@ -3699,6 +3777,13 @@ int main(int argc, char ** argv) {
3699
3777
return 1 ;
3700
3778
}
3701
3779
3780
+ PidFile f;
3781
+ if (!params.pidfile .empty ()) {
3782
+ if (is_old_pid_alive (params.pidfile ) || create_pidfile (params.pidfile , f)) {
3783
+ return 1 ;
3784
+ }
3785
+ }
3786
+
3702
3787
common_init ();
3703
3788
3704
3789
// struct that contains llama context and inference
0 commit comments