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