summaryrefslogtreecommitdiff
path: root/src/net/htcd.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/net/htcd.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/net/htcd.cc')
-rw-r--r--src/net/htcd.cc153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/net/htcd.cc b/src/net/htcd.cc
new file mode 100644
index 0000000..89729e6
--- /dev/null
+++ b/src/net/htcd.cc
@@ -0,0 +1,153 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <net/thrserv.h>
21
22static fp_stream merr(stderr);
23
24static mstring PATH;
25static htcServ* SERV;
26
27const mstring PIDURI="/sys/htcd";
28
29const int BACKLOG=4;
30const int SERVERS=9;
31const int LOWER=3;
32const int UPPER=6;
33const int KEEPALIVE=300;
34const int SNDBUFSIZE=16384;
35const int RCVBUFSIZE=16384;
36
37///////////////////////////////////////////////////////////
38
39static thrServ* server[SERVERS];
40static thrCron* crontab;
41
42extern "C" {
43 static void* thr_handler(void* p) { ((thrServ*)p)->enter(); return 0; }
44 static void* thr_cron(void* p) { ((thrCron*)p)->enter(); return 0; }
45 static void onTERM(int sig) { SERV->htcd.running=0; }
46 static void onHUP(int sig) { if(crontab) crontab->running=0; }
47 typedef void (*disp_t)(int);
48}
49
50static void MainProc(isocket& sock)
51{
52 int keep=1;
53 while(SERV->htcd.running) {
54 int nvacant=0; for(int i=0;i<SERVERS;i++) if(server[i]->vacant()) nvacant++;
55 if(nvacant>UPPER) keep=1; else if(nvacant<=LOWER) keep=0;
56 if(!keep) for(int i=0;i<SERVERS;i++) server[i]->shutdown();
57 time_t timeout=time(0)-KEEPALIVE;
58 for(int i=0;i<SERVERS;i++) if(timeout>server[i]->last) server[i]->disconnect();
59 int test=sock.test();
60 if(test>0) {
61 thrServ* p=0;
62 for(int i=0;i<SERVERS;i++) if(server[i]->vacant()) { p=server[i]; break; }
63 if(!p) for(int i=0;i<SERVERS;i++) if(!p||server[i]->first<p->first) p=server[i];
64 if(p->shutdown()) {
65 try {
66 isocket* s=sock.accept();
67 if(s) p->reset(s,keep);
68 }
69 catch(const merror_t& e) {
70 merr<<"SOCKET: "<<e.desc<<"\n";
71 }
72 }
73 }
74 else if(test<0) SERV->htcd.running=0;
75 }
76 for(int i=0;i<SERVERS;i++) {
77 server[i]->term();
78 pthread_join(server[i]->ptid,0);
79 }
80 pthread_kill(crontab->tid,SIGHUP);
81 pthread_join(crontab->ptid,0);
82}
83
84///////////////////////////////////////////////////////////////
85
86static void httpServer(int overport)
87{
88 isocket sock(SERV->htcd.node.addr,overport,BACKLOG);
89 sock.keepalive(1);
90 sock.sendbufsize(SNDBUFSIZE);
91 sock.recvbufsize(RCVBUFSIZE);
92
93 sigignore(SIGPIPE);
94 disp_t onterm=signal(SIGTERM,onTERM);
95 disp_t onint=signal(SIGINT,onTERM);
96 disp_t onhup=signal(SIGHUP,onHUP);
97 MainProc(sock);
98 signal(SIGHUP,onhup);
99 signal(SIGINT,onint);
100 signal(SIGTERM,onterm);
101}
102
103static void Daemon(int overport) try
104{
105 PROCLOCK(PATH+PIDURI);
106 SERV=new htcServ(PATH);
107 crontab=new thrCron(*SERV);
108 pthread_create(&crontab->ptid,0,thr_cron,crontab);
109 for(int i=0;i<SERVERS;i++) {
110 server[i]=new thrServ(*SERV);
111 pthread_create(&server[i]->ptid,0,thr_handler,server[i]);
112 }
113 merr<<"htcd: "<<PATH<<" started\n";
114 httpServer(overport<0?0:overport==0?SERV->htcd.port:overport);
115 merr<<"htcd: "<<PATH<<" terminating\n";
116 for(int i=0;i<SERVERS;i++) delete server[i];
117 delete crontab;
118}
119catch(const merror_t& e) {
120 if(SERV) {
121 SERV->htcd.errlog<<"["<<time(0)<<"][MAIN]["<<e.desc<<"]\n";
122 merr<<e.desc<<"\n";
123 }
124 else if(First(e.desc)!=sref("proclock:")) merr<<e.desc<<"\n";
125}
126catch(...) {
127 if(SERV) SERV->htcd.errlog<<"["<<time(0)<<"][MAIN][FATAL]\n";
128 merr<<"FATAL\n";
129}
130
131main(int argc,char* argv[]) try
132{
133 if(argc<3) {
134 merr<<"Usage: "<<argv[0]<<" <path> <overport=-1|0|port> [-1|0|1]\n";
135 return -1;
136 }
137 PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb();
138 setenv("DOCROOT",PATH.c_str(),1);
139 int overport=atoi(argv[2]);
140 int cmd=argc>3?atoi(argv[3]):0;
141 if(cmd) ProcTerminate(PATH+PIDURI);
142 if(cmd>=0) { if(fork()==0) Daemon(overport); }
143 delete SERV;
144 return 0;
145}
146catch(const merror_t& e) {
147 merr<<"ERROR: ["<<e.desc<<"]\n";
148 return -1;
149}
150catch(...) {
151 merr<<"ERROR: [FATAL]\n";
152 return -1;
153}