Browse Source

Some name cleanup and fixes,

added support of process restarting after child dies
master
Artyom Beilis 14 years ago
parent
commit
ae7a1d2952
4 changed files with 68 additions and 14 deletions
  1. +2
    -2
      TODO
  2. +5
    -3
      cache_pool.cpp
  3. +3
    -3
      config.js
  4. +58
    -6
      service.cpp

+ 2
- 2
TODO View File

@@ -4,6 +4,6 @@
Implement File Upload
- Implement Asynchronous API
- Implement JSON-RPC
- Reintegrate Sessions Support
- Reintegrate Cache Support
- Reintergrate Sessions over TCP/IP
- Reintegrate Cache Support over TCP/IP and shared_memory
- Update cppcms_tmpl_cc according to new code

+ 5
- 3
cache_pool.cpp View File

@@ -17,9 +17,11 @@ cache_pool::cache_pool(json::value const &settings) :
std::string type = settings.get("cache.backend","none");
if(type == "none" )
return;
if(type=="threaded") {
if(settings.get("service.procs",0)>1)
throw cppcms_error("Can't use `threaded' backend with more then one process");
if(type=="thread_shared") {
if(settings.get("service.worker_processes",0)>1)
throw cppcms_error(
"Can't use `thread_shared' backend with more then one process ether set "
"service.worker_processes to 0 or 1 or use cache.backend=\"process_shared\"");
unsigned items = settings.get("cache.limit",64);
d->module=impl::thread_cache_factory(items);
}


+ 3
- 3
config.js View File

@@ -5,8 +5,8 @@
"id" : 1,
// Service description
"service" : {
"procs" : 0,
"worker_threads": 5,
// "worker_processes" : 5,
"worker_threads" : 5,
"api" : "http",
"port" : 8080,
// "ip" : "0.0.0.0"
@@ -84,7 +84,7 @@
"auto_reload" : true
},
"cache" : {
"backend" : "threaded",
"backend" : "thread_shared",
"limit" : 100, // items
"memsize" : 64, // KBs
},


+ 58
- 6
service.cpp View File

@@ -312,7 +312,7 @@ void service::run()

int service::procs_no()
{
int procs=settings().get("service.procs",0);
int procs=settings().get("service.worker_processes",0);
if(procs < 0)
procs = 0;
#ifdef CPPCMS_WIN32
@@ -330,10 +330,11 @@ bool service::prefork()
return false;
}
#else // UNIX
static void dummy(int n) {}
bool service::prefork()
{
int procs=settings().get("service.procs",0);
if(procs<=0) {
int procs=procs_no();
if(procs==0) {
impl_->id_ = 1;
return false;
}
@@ -359,23 +360,74 @@ bool service::prefork()
}
}

sigset_t set;
sigset_t set,prev;
sigemptyset(&set);
sigaddset(&set,SIGTERM);
sigaddset(&set,SIGINT);
sigaddset(&set,SIGCHLD);
sigaddset(&set,SIGQUIT);

sigprocmask(SIG_BLOCK,&set,NULL);
sigprocmask(SIG_BLOCK,&set,&prev);

// Enable delivery of SIGCHLD
struct sigaction sa_new,sa_old;
memset(&sa_new,0,sizeof(sa_new));
sa_new.sa_handler=dummy;
::sigaction(SIGCHLD,&sa_new,&sa_old);

int sig;
do {
sig=0;
sigwait(&set,&sig);
if(sig==SIGCHLD) {
int status;
int pid = ::waitpid(0,&status,WNOHANG);
if(pid > 0) {
std::vector<int>::iterator p;
p = std::find(pids.begin(),pids.end(),pid);
// Ingnore all processes that are not my own childrens
if(p!=pids.end()) {
// TODO: Make better error handling
if(!WIFEXITED(stat) || WEXITSTATUS(stat)!=0){
if(WIFEXITED(stat)) {
std::cerr<<"Chaild exited with "<<WEXITSTATUS(stat)<<std::endl;
}
else if(WIFSIGNALED(stat)) {
std::cerr<<"Chaild killed by "<<WTERMSIG(stat)<<std::endl;
}
else {
std::cerr<<"Chaild exited for unknown reason"<<std::endl;
}
impl_->id_ = p - pids.begin() + 1;
*p=-1;
pid = ::fork();
if(pid < 0) {
int err=errno;
std::cerr<<"Failed to create process: " <<strerror(err)<<std::endl;
}
else if(pid == 0) {
::sigaction(SIGCHLD,&sa_old,NULL);
sigprocmask(SIG_SETMASK,&prev,NULL);
return false;
}
else {
*p=pid;
impl_->id_ = 0;
}
}
else {
*p=-1;
}
}
}
}
}while(sig!=SIGINT && sig!=SIGTERM && sig!=SIGQUIT);

sigprocmask(SIG_UNBLOCK,&set,NULL);
sigprocmask(SIG_SETMASK,&prev,NULL);

for(int i=0;i<procs;i++) {
if(pids[i]<0)
continue;
::kill(pids[i],SIGTERM);
int stat;
::waitpid(pids[i],&stat,0);


Loading…
Cancel
Save