add pidfile for daemon

This commit is contained in:
Cloud Wu
2014-05-23 13:24:02 +08:00
parent 1ce90b7d17
commit 8005b55ef5
8 changed files with 116 additions and 6 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
*.o *.o
*.a *.a
skynet skynet
skynet.pid
3rd/lua/lua 3rd/lua/lua
3rd/lua/luac 3rd/lua/luac
cservice cservice

View File

@@ -48,7 +48,7 @@ LUA_CLIB = skynet socketdriver int64 bson mongo md5 netpack \
SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \ SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \ skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \
skynet_harbor.c skynet_env.c skynet_monitor.c skynet_socket.c socket_server.c \ skynet_harbor.c skynet_env.c skynet_monitor.c skynet_socket.c socket_server.c \
malloc_hook.c malloc_hook.c skynet_daemon.c
all : \ all : \
$(SKYNET_BUILD_PATH)/skynet \ $(SKYNET_BUILD_PATH)/skynet \

View File

@@ -12,4 +12,4 @@ lualoader = "lualib/loader.lua"
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
snax = root.."examples/?.lua;"..root.."test/?.lua" snax = root.."examples/?.lua;"..root.."test/?.lua"
cpath = root.."cservice/?.so" cpath = root.."cservice/?.so"
daemon = false daemon = "./skynet.pid"

View File

@@ -0,0 +1,97 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/file.h>
#include <signal.h>
#include <errno.h>
#include "skynet_daemon.h"
static int
check_pid(const char *pidfile) {
int pid = 0;
FILE *f = fopen(pidfile,"r");
if (f == NULL)
return 0;
int n = fscanf(f,"%d", &pid);
fclose(f);
if (n !=1 || pid == 0 || pid == getpid()) {
return 0;
}
if (kill(pid, 0) && errno == ESRCH)
return 0;
return pid;
}
static int
write_pid(const char *pidfile) {
FILE *f;
int pid = 0;
int fd = open(pidfile, O_RDWR|O_CREAT, 0644);
if (fd == -1) {
fprintf(stderr, "Can't create %s.\n", pidfile);
return 0;
}
f = fdopen(fd, "r+");
if (f == NULL) {
fprintf(stderr, "Can't open %s.\n", pidfile);
return 0;
}
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
int n = fscanf(f, "%d", &pid);
fclose(f);
if (n != 1) {
fprintf(stderr, "Can't lock and read pidfile.\n");
} else {
fprintf(stderr, "Can't lock pidfile, lock is held by pid %d.\n", pid);
}
return 0;
}
pid = getpid();
if (!fprintf(f,"%d\n", pid)) {
fprintf(stderr, "Can't write pid.\n");
close(fd);
return 0;
}
fflush(f);
if (flock(fd, LOCK_UN) == -1) {
fprintf(stderr, "Can't unlock pidfile %s.\n", pidfile);
close(fd);
return 0;
}
close(fd);
return pid;
}
int
daemon_init(const char *pidfile) {
int pid = check_pid(pidfile);
if (pid) {
fprintf(stderr, "Skynet is already running, pid = %d.\n", pid);
return 1;
}
if (daemon(1,0)) {
fprintf(stderr, "Can't daemonize.\n");
return 1;
}
pid = write_pid(pidfile);
if (pid == 0) {
return 1;
}
return 0;
}
int
daemon_exit(const char *pidfile) {
return unlink (pidfile);
}

View File

@@ -0,0 +1,7 @@
#ifndef skynet_daemon_h
#define skynet_daemon_h
int daemon_init(const char *pidfile);
int daemon_exit(const char *pidfile);
#endif

View File

@@ -4,7 +4,7 @@
struct skynet_config { struct skynet_config {
int thread; int thread;
int harbor; int harbor;
int daemon; const char * daemon;
const char * module_path; const char * module_path;
const char * bootstrap; const char * bootstrap;
}; };

View File

@@ -24,6 +24,7 @@ optint(const char *key, int opt) {
return strtol(str, NULL, 10); return strtol(str, NULL, 10);
} }
/*
static int static int
optboolean(const char *key, int opt) { optboolean(const char *key, int opt) {
const char * str = skynet_getenv(key); const char * str = skynet_getenv(key);
@@ -33,6 +34,7 @@ optboolean(const char *key, int opt) {
} }
return strcmp(str,"true")==0; return strcmp(str,"true")==0;
} }
*/
static const char * static const char *
optstring(const char *key,const char * opt) { optstring(const char *key,const char * opt) {
@@ -112,7 +114,7 @@ main(int argc, char *argv[]) {
config.module_path = optstring("cpath","./cservice/?.so"); config.module_path = optstring("cpath","./cservice/?.so");
config.harbor = optint("harbor", 1); config.harbor = optint("harbor", 1);
config.bootstrap = optstring("bootstrap","snlua bootstrap"); config.bootstrap = optstring("bootstrap","snlua bootstrap");
config.daemon = optboolean("daemon", 0); config.daemon = optstring("daemon", NULL);
lua_close(L); lua_close(L);

View File

@@ -7,6 +7,7 @@
#include "skynet_timer.h" #include "skynet_timer.h"
#include "skynet_monitor.h" #include "skynet_monitor.h"
#include "skynet_socket.h" #include "skynet_socket.h"
#include "skynet_daemon.h"
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
@@ -196,8 +197,7 @@ bootstrap(const char * cmdline) {
void void
skynet_start(struct skynet_config * config) { skynet_start(struct skynet_config * config) {
if (config->daemon) { if (config->daemon) {
if (daemon(1,0)) { if (daemon_init(config->daemon)) {
fprintf(stderr, "daemon error");
exit(1); exit(1);
} }
} }
@@ -212,4 +212,7 @@ skynet_start(struct skynet_config * config) {
_start(config->thread); _start(config->thread);
skynet_socket_free(); skynet_socket_free();
if (config->daemon) {
daemon_exit(config->daemon);
}
} }