1515#define MIMETYPE_JSON " application/json; charset=utf-8"
1616
1717// 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 >
2020
2121#include < atomic>
2222#include < chrono>
23+ #include < cinttypes>
2324#include < condition_variable>
2425#include < cstddef>
25- #include < cinttypes>
2626#include < deque>
2727#include < memory>
2828#include < mutex>
29- #include < signal.h>
3029#include < thread>
3130#include < unordered_map>
3231#include < unordered_set>
3332
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+
3441using json = nlohmann::ordered_json;
3542
3643constexpr int HTTP_POLLING_SECONDS = 1 ;
@@ -3691,6 +3698,77 @@ inline void signal_handler(int signal) {
36913698 shutdown_handler (signal);
36923699}
36933700
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+
36943772int main (int argc, char ** argv) {
36953773 // own arguments required by this example
36963774 common_params params;
@@ -3699,6 +3777,13 @@ int main(int argc, char ** argv) {
36993777 return 1 ;
37003778 }
37013779
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+
37023787 common_init ();
37033788
37043789 // struct that contains llama context and inference
0 commit comments