Skip to content

Commit 57507f3

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 57507f3

File tree

3 files changed

+97
-5
lines changed

3 files changed

+97
-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: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,32 @@
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+
typedef int pid_t;
39+
#else
40+
#include <unistd.h>
41+
#endif
42+
3443
using json = nlohmann::ordered_json;
3544

3645
constexpr int HTTP_POLLING_SECONDS = 1;
@@ -3691,6 +3700,77 @@ inline void signal_handler(int signal) {
36913700
shutdown_handler(signal);
36923701
}
36933702

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+
36943774
int main(int argc, char ** argv) {
36953775
// own arguments required by this example
36963776
common_params params;
@@ -3699,6 +3779,13 @@ int main(int argc, char ** argv) {
36993779
return 1;
37003780
}
37013781

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+
37023789
common_init();
37033790

37043791
// struct that contains llama context and inference

0 commit comments

Comments
 (0)