Skip to content

Commit 7e9ce12

Browse files
committed
server : add pidfile option
So we can track the pid of this process Signed-off-by: Eric Curtin <[email protected]>
1 parent 860a9e4 commit 7e9ce12

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

common/arg.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3373,5 +3373,9 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
33733373
}
33743374
).set_examples({LLAMA_EXAMPLE_SERVER}));
33753375

3376+
add_opt(common_arg({ "--pidfile" }, "FILE", "path to PID file for server process",
3377+
[](common_params & params, const std::string & value) { params.pidfile = value; })
3378+
.set_examples({ LLAMA_EXAMPLE_SERVER }));
3379+
33763380
return ctx_arg;
33773381
}

common/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ struct common_params {
366366
std::string hostname = "127.0.0.1";
367367
std::string public_path = ""; // NOLINT
368368
std::string chat_template = ""; // NOLINT
369+
std::string pidfile = ""; // path to PID file for server process // NOLINT
369370
bool use_jinja = false; // NOLINT
370371
bool enable_chat_template = true;
371372
common_reasoning_format reasoning_format = COMMON_REASONING_FORMAT_DEEPSEEK;

tools/server/server.cpp

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,31 @@
1414
// mime type for sending response
1515
#define MIMETYPE_JSON "application/json; charset=utf-8"
1616

17-
// auto generated files (see README.md for details)
18-
#include "index.html.gz.hpp"
19-
#include "loading.html.hpp"
17+
#include <signal.h>
2018

2119
#include <atomic>
2220
#include <chrono>
21+
#include <cinttypes>
2322
#include <condition_variable>
2423
#include <cstddef>
25-
#include <cinttypes>
2624
#include <deque>
2725
#include <memory>
2826
#include <mutex>
29-
#include <signal.h>
3027
#include <thread>
3128
#include <unordered_map>
3229
#include <unordered_set>
3330

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+
3442
using json = nlohmann::ordered_json;
3543

3644
constexpr int HTTP_POLLING_SECONDS = 1;
@@ -3691,6 +3699,77 @@ inline void signal_handler(int signal) {
36913699
shutdown_handler(signal);
36923700
}
36933701

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+
36943773
int main(int argc, char ** argv) {
36953774
// own arguments required by this example
36963775
common_params params;
@@ -3699,6 +3778,13 @@ int main(int argc, char ** argv) {
36993778
return 1;
37003779
}
37013780

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+
37023788
common_init();
37033789

37043790
// struct that contains llama context and inference

0 commit comments

Comments
 (0)