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
+ #else
39
+ #include < unistd.h>
40
+ #endif
41
+
34
42
using json = nlohmann::ordered_json;
35
43
36
44
constexpr int HTTP_POLLING_SECONDS = 1 ;
@@ -3691,6 +3699,77 @@ inline void signal_handler(int signal) {
3691
3699
shutdown_handler (signal);
3692
3700
}
3693
3701
3702
+ static bool check_pid_alive (const pid_t pid) {
3703
+ if (pid <= 0 ) {
3704
+ return false ;
3705
+ }
3706
+
3707
+ // Process is alive or exists but is inaccessible
3708
+ if (kill (pid, 0 ) == 0 || errno == EPERM) {
3709
+ return true ; // Process is alive
3710
+ }
3711
+
3712
+ return false ; // Process does not exist or other error
3713
+ }
3714
+
3715
+ class PidFile {
3716
+ public:
3717
+ FILE * file = nullptr ;
3718
+ std::string fname;
3719
+ bool rm = false ;
3720
+
3721
+ FILE * open (const std::string & filename, const char * mode, const bool r = false ) {
3722
+ file = ggml_fopen (filename.c_str (), mode);
3723
+ fname = filename;
3724
+ rm = r;
3725
+
3726
+ return file;
3727
+ }
3728
+
3729
+ void close () {
3730
+ fclose (file);
3731
+ file = nullptr ;
3732
+
3733
+ if (rm) {
3734
+ // Remove stale pidfile
3735
+ unlink (fname.c_str ());
3736
+ }
3737
+ }
3738
+
3739
+ ~PidFile () {
3740
+ if (file) {
3741
+ close ();
3742
+ }
3743
+ }
3744
+ };
3745
+
3746
+ static bool is_old_pid_alive (const std::string & filename) {
3747
+ pid_t oldpid = 0 ;
3748
+ PidFile f;
3749
+ if (f.open (filename, " r" )) {
3750
+ if (fscanf (f.file , " %d" , &oldpid) == 1 ) {
3751
+ if (check_pid_alive (oldpid)) {
3752
+ LOG_ERR (" Process already running with PID %d\n " , oldpid);
3753
+ return true ;
3754
+ }
3755
+ }
3756
+ }
3757
+
3758
+ return false ;
3759
+ }
3760
+
3761
+ static int create_pidfile (const std::string & pidfile, PidFile & f) {
3762
+ if (!f.open (pidfile.c_str (), " w" , true )) {
3763
+ LOG_ERR (" Unable to open pidfile %s: %s\n " , pidfile.c_str (), strerror (errno));
3764
+ return -1 ;
3765
+ }
3766
+
3767
+ fprintf (f.file , " %d\n " , getpid ());
3768
+ fflush (f.file );
3769
+
3770
+ return 0 ;
3771
+ }
3772
+
3694
3773
int main (int argc, char ** argv) {
3695
3774
// own arguments required by this example
3696
3775
common_params params;
@@ -3699,6 +3778,13 @@ int main(int argc, char ** argv) {
3699
3778
return 1 ;
3700
3779
}
3701
3780
3781
+ PidFile f;
3782
+ if (!params.pidfile .empty ()) {
3783
+ if (is_old_pid_alive (params.pidfile ) || create_pidfile (params.pidfile , f)) {
3784
+ return 1 ;
3785
+ }
3786
+ }
3787
+
3702
3788
common_init ();
3703
3789
3704
3790
// struct that contains llama context and inference
0 commit comments