#include "lcw_shttpd.h"
static int workersnum = 0;
extern struct conf_opts conf_para;
pthread_mutex_t thread_init = PTHREAD_MUTEX_INITIALIZER;
int WORKER_ISSTATUS(int status);
static struct worker_ctl *wctls = NULL;
void Worker_Init();
int Worker_Add(int i);
void Worker_Delete(int i);
void Worker_Destory();
/******************************************************
函数名:do_work(struct worker_ctl *wctl)
参数:控制结构
功能:执行任务
*******************************************************/
static void do_work(struct worker_ctl *wctl)
{
DBGPRINT("LCW==>do_work\n");
struct timeval tv;
fd_set rfds;
int fd = wctl->conn.cs;
struct vec *req = &wctl->conn.con_req.req;
int retval = 1;
for(;retval > 0;)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 300;
tv.tv_usec = 0;
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
switch(retval)
{
case -1:
close(fd);
break;
case 0:
close(fd);
break;
default:
printf("select retval:%d\n",retval);
if(FD_ISSET(fd, &rfds))
{
memset(wctl->conn.dreq, 0, sizeof(wctl->conn.dreq));
req->len = read(wctl->conn.cs, wctl->conn.dreq, sizeof(wctl->conn.dreq));
req->ptr = wctl->conn.dreq;
DBGPRINT("Read %d bytes,'%s'\n",req->len,req->ptr);
if(req->len > 0)
{
wctl->conn.con_req.err = Request_Parse(wctl);
Request_Handle(wctl);
}
else
{
close(fd);
retval = -1;
}
}
}
}
DBGPRINT("LCW<==do_work\n");
}
/******************************************************
函数名:worker(void *arg)
参数:worker_ctl *wctls
功能:线程处理函数
*******************************************************/
static void* worker(void *arg)
{
DBGPRINT("LCW==>worker\n");
struct worker_ctl *ctl = (struct worker_ctl *)arg;
struct worker_opts *self_opts = &ctl->opts;
pthread_mutex_unlock(&thread_init);
self_opts->flags = WORKER_IDEL;
for(;self_opts->flags != WORKER_DETACHING;)
{
int err = pthread_mutex_trylock(&self_opts->mutex);
if(err)
{
sleep(1);
continue;
}
else
{
DBGPRINT("Do task\n");
self_opts->flags = WORKER_RUNNING;
do_work(ctl);
close(ctl->conn.cs);
ctl->conn.cs = -1;
if(self_opts->flags == WORKER_DETACHING)
break;
else
self_opts->flags = WORKER_IDEL;
}
}
self_opts->flags = WORKER_DETACHED;
workersnum--;
DBGPRINT("LCW<==worker\n");
return NULL;
}
/******************************************************
函数名:WORKER_ISSTATUS(int status)
参数:欲查询的线程状态
功能:查询线程状态
*******************************************************/
int WORKER_ISSTATUS(int status)
{
int i = 0;
for(i = 0; i<conf_para.MaxClient;i++)
{
if(wctls[i].opts.flags == status)
return i;
}
return -1;
}
/*****************************************************
函数名:Worker_Init()
参数:无
功能:初始化线程
******************************************************/
void Worker_Init()
{
DBGPRINT("LCW==>Worker_Init");
int i = 0;
wctls = (struct worker_ctl*)malloc( sizeof(struct worker_ctl)*conf_para.MaxClient);
memset(wctls,0, sizeof(*wctls)*conf_para.MaxClient);
for(i=0;i<conf_para.MaxClient;i++)
{
wctls[i].opts.work = &wctls[i];
wctls[i].conn.work = &wctls[i];
wctls[i].opts.flags = WORKER_DETACHED;
pthread_mutex_init(&wctls[i].opts.mutex,NULL);
pthread_mutex_lock(&wctls[i].opts.mutex);
wctls[i].conn.con_req.conn = &wctls[i].conn;
wctls[i].conn.con_res.conn = &wctls[i].conn;
wctls[i].conn.cs = -1;
wctls[i].conn.con_req.req.ptr = wctls[i].conn.dreq;
wctls[i].conn.con_req.head = wctls[i].conn.dreq;
wctls[i].conn.con_req.uri = wctls[i].conn.dreq;
wctls[i].conn.con_res.fd = -1;
wctls[i].conn.con_res.res.ptr = wctls[i].conn.dres;
}
for (i = 0; i < conf_para.InitClient;i++)
{
Worker_Add(i);
}
DBGPRINT("LCW<==Worker_Init\n");
}
/******************************************************
函数名:Worker_Add(int i)
参数:
功能:增加线程
*******************************************************/
int Worker_Add(int i)
{
DBGPRINT("LCW==>Worker_Add\n");
pthread_t th;
int err = -1;
if (wctls[i].opts.flags == WORKER_RUNNING)
{
return 1;
}
pthread_mutex_lock(&thread_init);
wctls[i].opts.flags = WORKER_INITED;
err = pthread_create(&th, NULL, worker, (void*)&wctls[i]);
pthread_mutex_unlock(&thread_init);
wctls[i].opts.th = th;
workersnum++;
DBGPRINT("LCW<==Worker_Add\n");
return 0;
}
/******************************************************
函数名:Worker_Delete(int i)
参数:线程序号
功能:减少线程
*******************************************************/
void Worker_Delete(int i)
{
DBGPRINT("LCW==>Worker_Delete\n");
wctls[i].opts.flags = WORKER_DETACHING;
DBGPRINT("LCW<==Worker_Delete\n");
}
/******************************************************
函数名:Worker_Destory()
参数:
功能:销毁线程
*******************************************************/
void Worker_Destory()
{
DBGPRINT("LCW==>Worker_Destory\n");
int i = 0;
int clean = 0;
for(i=0;i<conf_para.MaxClient;i++)
{
DBGPRINT("thread %d,status %d\n",i,wctls[i].opts.flags );
if(wctls[i].opts.flags != WORKER_DETACHED)
Worker_Delete(i);
}
while(!clean)
{
clean = 1;
for(i = 0; i<conf_para.MaxClient;i++)
{
DBGPRINT("thread %d,status %d\n",i,wctls[i].opts.flags );
if(wctls[i].opts.flags == WORKER_RUNNING || wctls[i].opts.flags == WORKER_DETACHING)
clean = 0;
}
if(!clean)
sleep(1);
}
DBGPRINT("LCW<==Worker_Destory\n");
}
#define STATUS_RUNNING 1
#define STATSU_STOP 0
static int SCHEDULESTATUS = STATUS_RUNNING;
/******************************************************
函数名:Worker_ScheduleRun(int ss)
参数:文件描述符
功能:当有客户端连接到来的时候,将客户端连接分配给空闲客户端,由客户端处理到来的请求
*******************************************************/
int Worker_ScheduleRun(int ss)
{
DBGPRINT("LCW==>Worker_ScheduleRun!!!\n");
struct sockaddr_in client;
socklen_t len = sizeof(client);
Worker_Init();
int i = 0;
for(;SCHEDULESTATUS== STATUS_RUNNING;)
{
struct timeval tv;
fd_set rfds;
int retval = -1;
FD_ZERO(&rfds);
FD_SET(ss, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 500000;
retval = select(ss + 1, &rfds, NULL, NULL, &tv);
switch(retval)
{
case -1:
case 0:
continue;
break;
default:
if(FD_ISSET(ss, &rfds))
{
int sc = accept(ss, (struct sockaddr*)&client, &len);
printf("client comming\n");
i = WORKER_ISSTATUS(WORKER_IDEL);
if(i == -1)
{
i = WORKER_ISSTATUS(WORKER_DETACHED);
if(i != -1)
Worker_Add(i);
}
if(i != -1)
{
wctls[i].conn.cs = sc;
pthread_mutex_unlock(&wctls[i].opts.mutex);
}
}
}
}
DBGPRINT("LCW<==Worker_ScheduleRun\n");
return 0;
}
/******************************************************
函数名:Worker_ScheduleStop()
参数:
功能:停止调度过程
*******************************************************/
int Worker_ScheduleStop()
{
DBGPRINT("LCW==>Worker_ScheduleStop\n");
SCHEDULESTATUS = STATSU_STOP;
int i =0;
Worker_Destory();
int allfired = 0;
for(;!allfired;)
{
allfired = 1;
for(i = 0; i<conf_para.MaxClient;i++)
{
int flags = wctls[i].opts.flags;
if(flags == WORKER_DETACHING || flags == WORKER_IDEL)
allfired = 0;
}
}
pthread_mutex_destroy(&thread_init);
for(i = 0; i<conf_para.MaxClient;i++)
pthread_mutex_destroy(&wctls[i].opts.mutex);
free(wctls);
DBGPRINT("LCW<==Worker_ScheduleStop\n");
return 0;
}