Beispiel #1
0
int swReactorPoll_create(swReactor *reactor, int max_fd_num)
{
	//create reactor object
	swReactorPoll *object = sw_malloc(sizeof(swReactorPoll));
	if (object == NULL)
	{
		swError("malloc[0] failed");
		return SW_ERR;
	}
	bzero(object, sizeof(swReactorPoll));

	object->fds = sw_calloc(max_fd_num, sizeof(swPollFdInfo));
	if (object->fds == NULL)
	{
		swError("malloc[1] failed");
		return SW_ERR;
	}
	object->events = sw_calloc(max_fd_num, sizeof(struct pollfd));
	if (object->events == NULL)
	{
		swError("malloc[2] failed");
		return SW_ERR;
	}
	object->max_fd_num = max_fd_num;
	bzero(reactor->handle, sizeof(reactor->handle));
	reactor->object = object;
	//binding method
	reactor->add = swReactorPoll_add;
	reactor->del = swReactorPoll_del;
	reactor->set = swReactorPoll_set;
	reactor->wait = swReactorPoll_wait;
	reactor->free = swReactorPoll_free;
	reactor->setHandle = swReactor_setHandle;
	return SW_OK;
}
Beispiel #2
0
/**
 * worker main loop
 */
int swWorker_loop(swFactory *factory, int worker_id)
{
    swServer *serv = factory->ptr;

#ifndef SW_WORKER_USE_SIGNALFD
    SwooleG.use_signalfd = 0;
#endif

    //worker_id
    SwooleWG.id = worker_id;
    SwooleWG.request_count = 0;
    SwooleG.pid = getpid();

    //signal init
    swWorker_signal_init();
    swWorker *worker = swServer_get_worker(serv, worker_id);
    swServer_worker_init(serv, worker);

    SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
    if (SwooleG.main_reactor == NULL)
    {
        swError("[Worker] malloc for reactor failed.");
        return SW_ERR;
    }

    if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0)
    {
        swError("[Worker] create worker_reactor failed.");
        return SW_ERR;
    }
    
    serv->workers[worker_id].status = SW_WORKER_IDLE;

    int pipe_worker = serv->workers[worker_id].pipe_worker;

    swSetNonBlock(pipe_worker);
    SwooleG.main_reactor->ptr = serv;
    //这里的add函数是epoll的add函数
    SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite);

    swWorker_onStart(serv);

#ifdef HAVE_SIGNALFD
    if (SwooleG.use_signalfd)
    {
        swSignalfd_setup(SwooleG.main_reactor);
    }
#endif
    //main loop
    SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL);
    //clear pipe buffer
    swWorker_clean();
    //worker shutdown
    swWorker_onStop(serv);
    return SW_OK;
}
Beispiel #3
0
void swoole_init(void)
{
    struct rlimit rlmt;
    if (SwooleG.running == 0)
    {
        bzero(&SwooleG, sizeof(SwooleG));
        bzero(sw_error, SW_ERROR_MSG_SIZE);

        //初始化全局变量
        SwooleG.running = 1;
        sw_errno = 0;

        SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
        SwooleG.pagesize = getpagesize();

        if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0)
        {
            swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno);
        }
        else
        {
            SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur;
        }

        //random seed
        srandom(time(NULL));

        //init global lock
        swMutex_create(&SwooleG.lock, 0);

        //init signalfd
#ifdef HAVE_SIGNALFD
        swSignalfd_init();
        SwooleG.use_signalfd = 1;
#endif
        //timerfd
#ifdef HAVE_TIMERFD
        SwooleG.use_timerfd = 1;
#endif
        SwooleG.use_timer_pipe = 1;
        //将日志设置为标准输出
        SwooleG.log_fd = STDOUT_FILENO;
        //初始化全局内存
        SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1);
        if (SwooleG.memory_pool == NULL)
        {
            swError("[Master] Fatal Error: create global memory fail. Error: %s[%d]", strerror(errno), errno);
        }
        SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS));
        if (SwooleGS == NULL)
        {
            swError("[Master] Fatal Error: alloc memory for SwooleGS fail. Error: %s[%d]", strerror(errno), errno);
        }
    }
}
Beispiel #4
0
static int swFactoryProcess_writer_start(swFactory *factory)
{
	swFactoryProcess *this = factory->object;
	swThreadParam *param;
	int i;
	pthread_t pidt;
	swThreadStartFunc thread_main;

#ifdef SW_USE_SHM_CHAN
	thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_ex;

#else
	thread_main = (swThreadStartFunc)swFactoryProcess_writer_loop;
#endif

	for (i = 0; i < this->writer_num; i++)
	{
		param = sw_malloc(sizeof(swThreadParam));
		if (param == NULL )
		{
			swError("malloc fail\n");
			return SW_ERR;
		}

#ifdef SW_USE_SHM_CHAN
#if defined(SW_CHAN_USE_MMAP) || SW_CHAN_USE_MMAP==1
		mm = swShareMemory_mmap_create(&this->writers[i].shm, SW_CHAN_BUFFER_SIZE, 0);
#else
		mm = swShareMemory_sysv_create(&this->writers[i].shm, SW_CHAN_BUFFER_SIZE, SW_CHAN_SYSV_KEY);
#endif
		if (mm == NULL )
		{
			swError("shm_create fail\n");
			return SW_ERR;
		}
		if (swChan_create(&this->writers[i].chan, mm, SW_CHAN_BUFFER_SIZE, SW_CHAN_ELEM_SIZE) < 0)
		{
			swError("swChan_create fail\n");
			return SW_ERR;
		}
#endif
		param->object = factory;
		param->pti = i;

		if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0)
		{
			swTrace("pthread_create fail\n");
			return SW_ERR;
		}
		this->writers[i].ptid = pidt;
		SW_START_SLEEP;
	}
	return SW_OK;
}
Beispiel #5
0
static int swFactoryProcess_writer_start(swFactory *factory)
{
	swFactoryProcess *object = factory->object;
	swThreadParam *param;
	int i;
	pthread_t pidt;
	swThreadStartFunc thread_main;

#if SW_WORKER_IPC_MODE == 2
	thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_queue;
#else
	thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_unsock;
#endif

	for (i = 0; i < object->writer_num; i++)
	{
		param = sw_malloc(sizeof(swPipe));
		if (param == NULL)
		{
			swError("malloc fail\n");
			return SW_ERR;
		}
		param->object = factory;
		param->pti = i;
		if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0)
		{
			swTrace("pthread_create fail\n");
			return SW_ERR;
		}
		pthread_detach(pidt);
		object->writers[i].ptid = pidt;
		SW_START_SLEEP;
	}
	return SW_OK;
}
Beispiel #6
0
static int swReactorPoll_add(swReactor *reactor, int fd, int fdtype)
{
	swReactorPoll *object = reactor->object;
	int cur = reactor->event_num;
	if (reactor->event_num == object->max_fd_num)
	{
		swError("too many connection, more than %d", object->max_fd_num);
		return SW_ERR;
	}
	object->fds[cur].fdtype = swReactor_fdtype(fdtype);
	object->events[cur].fd = fd;
	//object->events[cur].events = POLLRDHUP;
	object->events[cur].events = 0;

	if (swReactor_event_read(fdtype))
	{
		object->events[cur].events |= POLLIN;
	}
	if (swReactor_event_write(fdtype))
	{
		object->events[cur].events |= POLLOUT;
	}
	if (swReactor_event_error(fdtype))
	{
		object->events[cur].events |= POLLHUP;
	}
	reactor->event_num++;
	return SW_OK;
}
Beispiel #7
0
static int swFactoryProcess_writer_start(swFactory *factory)
{
	swServer *serv = SwooleG.serv;
	swThreadParam *param;
	int i;
	pthread_t pidt;
	swThreadStartFunc thread_main;

	if (serv->ipc_mode == SW_IPC_MSGQUEUE)
	{
		thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_queue;
	}
	else
	{
#if SW_USE_WRITER_THREAD
		thread_main = (swThreadStartFunc) swFactoryProcess_writer_loop_unsock;
#else
		swError("never get here");
#endif
	}

	for (i = 0; i < serv->writer_num; i++)
	{
		param = sw_malloc(sizeof(swPipe));
		if (param == NULL)
		{
			swError("malloc fail\n");
			return SW_ERR;
		}
		param->object = factory;
		param->pti = i;
		if (pthread_create(&pidt, NULL, thread_main, (void *) param) < 0)
		{
			swTrace("pthread_create fail\n");
			return SW_ERR;
		}
		pthread_detach(pidt);
		serv->writer_threads[i].ptid = pidt;
		SW_START_SLEEP;
	}
	return SW_OK;
}
Beispiel #8
0
void swSignalfd_init()
{
	sigemptyset(&swoole_signalfd_mask);
	object.items = sw_calloc(SW_SIGNAL_INIT_NUM, sizeof(swSignal_item));
	if (object.items == NULL)
	{
		swError("malloc for swSignal_item failed.");
	}
	object.size = SW_SIGNAL_INIT_NUM;
	object.num = 0;
}
Beispiel #9
0
/**
 * 主进程向worker进程发送数据
 * @param worker_id 发到指定的worker进程
 */
int swFactoryProcess_send2worker(swFactory *factory, swEventData *data, int worker_id)
{
	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;
	int pti;
	int ret;
	int send_len = sizeof(data->info) + data->info.len;

	if (worker_id < 0)
	{
		//轮询
		// data->info.from_id > serv->poll_thread_num, UDP必须使用轮询
		if (serv->dispatch_mode == SW_DISPATCH_ROUND || data->info.from_id > serv->poll_thread_num)
		{
			pti = (object->worker_pti++) % object->worker_num;
		}
		//使用fd取摸来散列
		else if (serv->dispatch_mode == SW_DISPATCH_FDMOD)
		{
			pti = data->info.fd % object->worker_num;
		}
		//使用抢占式队列(IPC消息队列)分配
		else
		{
#if SW_WORKER_IPC_MODE != 2
			swError("SW_DISPATCH_QUEUE must use (SW_WORKER_IPC_MODE = 2)");
#endif
			//msgsnd参数必须>0
			//worker进程中正确的mtype应该是pti + 1
			pti = object->worker_num;
		}
	}
	//指定了worker_id
	else
	{
		pti = worker_id;
	}

#if SW_WORKER_IPC_MODE == 2
	//insert to msg queue
	swQueue_data *in_data = (swQueue_data *)((void *)data - sizeof(long));

	//加1防止id为0的worker进程出错
	in_data->mtype = pti + 1;

	swDataHead *info = (swDataHead *)in_data->mdata;
	ret = object->rd_queue.in(&object->rd_queue, in_data, send_len);
	swTrace("[Master]rd_queue[%ld]->in: fd=%d|type=%d|len=%d", in_data->mtype, info->fd, info->type, info->len);
#else
	//send to unix sock
	ret = swWrite(object->workers[pti].pipe_master, (char *) data, send_len);
#endif
	return ret;
}
Beispiel #10
0
void swoole_init(void)
{
	if (SwooleG.running == 0)
	{
		bzero(&SwooleG, sizeof(SwooleG));
		bzero(sw_error, SW_ERROR_MSG_SIZE);

		//初始化全局变量
		SwooleG.running = 1;
		sw_errno = 0;

		//init global lock
		swMutex_create(&SwooleG.lock, 0);

		//init signalfd
#ifdef HAVE_SIGNALFD
		swSignalfd_init();
		SwooleG.use_signalfd = 1;
#endif

		//timerfd
#ifdef HAVE_TIMERFD
		SwooleG.use_timerfd = 1;
#endif
		//将日志设置为标准输出
		SwooleG.log_fd = STDOUT_FILENO;
		//初始化全局内存
		SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1);
		if(SwooleG.memory_pool == NULL)
		{
			swError("[Master] Fatal Error: create global memory fail. Error: %s[%d]", strerror(errno), errno);
		}
		SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS));
		if(SwooleGS == NULL)
		{
			swError("[Master] Fatal Error: alloc memory for SwooleGS fail. Error: %s[%d]", strerror(errno), errno);
		}

	}
}
Beispiel #11
0
int swRingQueue_init(swRingQueue * p_queue, int buffer_size)
{
	p_queue->data = sw_calloc(buffer_size, sizeof(void*));
	if(p_queue->data == NULL)
	{
		swError("malloc fail\n");
		return -1;
	}
	p_queue->size = buffer_size;
	p_queue->head = 0;
	p_queue->tail = 0;
	p_queue->tag = 0;
	return 0;
}
Beispiel #12
0
void swSignalfd_add(int signo, __sighandler_t callback)
{
	if (object.num == object.size)
	{
		object.items = sw_realloc(object.items, sizeof(swSignal_item) * object.size * 2);
		if (object.items == NULL)
		{
			swError("realloc for swSignal_item failed.");
			return;
		}
		object.size = object.size * 2;
	}
	sigaddset(&swoole_signalfd_mask, signo);
	object.items[object.num].callback = callback;
	object.items[object.num].signo = signo;
	object.num ++;
}
Beispiel #13
0
int swFactoryProcess_controller_start(swFactory *factory)
{
	int i, pid;
	swController *controller;

	//循环fork
	LL_FOREACH(manager_controller_list, controller)
	{
		controller->pipe_fd = manager_controller_pipes[controller->id].pipes[1];
		pid = swFactoryProcess_controller_spawn(factory, controller);
		if(pid < 0)
		{
			swError("Fork controller process fail.Errno=%d", errno);
			return SW_ERR;
		}
		else
		{
			controller->pid = pid;
		}
	}
Beispiel #14
0
int swSocket_create(int type)
{
    int _domain;
    int _type;

    switch (type)
    {
    case SW_SOCK_TCP:
        _domain = PF_INET;
        _type = SOCK_STREAM;
        break;
    case SW_SOCK_TCP6:
        _domain = PF_INET6;
        _type = SOCK_STREAM;
        break;
    case SW_SOCK_UDP:
        _domain = PF_INET;
        _type = SOCK_DGRAM;
        break;
    case SW_SOCK_UDP6:
        _domain = PF_INET6;
        _type = SOCK_DGRAM;
        break;
    case SW_SOCK_UNIX_DGRAM:
        _domain = PF_UNIX;
        _type = SOCK_DGRAM;
        break;
    case SW_SOCK_UNIX_STREAM:
        _domain = PF_UNIX;
        _type = SOCK_STREAM;
        break;
    default:
        swError("unknow socket type [%d]", type);
        return SW_ERR;
    }
    return socket(_domain, _type, 0);
}
Beispiel #15
0
static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti)
{
	struct {
		long pti;
		swEventData req;
	} rdata;

	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;

	int pipe_rd = object->workers[worker_pti].pipe_worker;
	int n;

	c_worker_pti = worker_pti;
	object->manager_pid = getppid();

#if SW_WORKER_IPC_MODE == 2
	//抢占式,使用相同的队列type
	if (serv->dispatch_mode == SW_DISPATCH_QUEUE)
	{
		//这里必须加1
		rdata.pti = serv->worker_num + 1;
	}
	else
	{
		//必须加1
		rdata.pti = worker_pti + 1;
	}
#else
	SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
	if(SwooleG.main_reactor == NULL)
	{
		swError("[Worker] malloc for reactor fail");
		return SW_ERR;
	}
	if(swReactor_auto(SwooleG.main_reactor, serv->max_conn) < 0)
	{
		swError("[Worker] create worker_reactor fail");
		return SW_ERR;
	}
	SwooleG.main_reactor->ptr = serv;
	SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE);
	SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive);
#endif

	if(factory->max_request < 1)
	{
		worker_task_always = 1;
	}
	else
	{
		worker_task_num = factory->max_request;
		worker_task_num += get_rand(worker_pti);
	}

#ifdef HAVE_CPU_AFFINITY
	if (serv->open_cpu_affinity == 1)
	{
		cpu_set_t cpu_set;
		CPU_ZERO(&cpu_set);
		CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set);
		if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set))
		{
			swWarn("pthread_setaffinity_np set fail\n");
		}
	}
#endif
	if (serv->onWorkerStart != NULL)
	{
		//worker进程启动时调用
		serv->onWorkerStart(serv, worker_pti);
	}
	struct timeval timeo;
	timeo.tv_sec = SW_REACTOR_TIMEO_SEC;
	timeo.tv_usec = SW_REACTOR_TIMEO_USEC;

#if SW_WORKER_IPC_MODE == 2
	//主线程
	while (swoole_running > 0)
	{
		n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req));
		if (n < 0)
		{
			swWarn("[Worker]rd_queue[%ld]->out wait. Error: %s [%d]", rdata.pti, strerror(errno), errno);
			continue;
		}
		swFactoryProcess_worker_excute(factory, &rdata.req);
	}
#else
	SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo);
#endif
	if (serv->onWorkerStop != NULL)
	{
		//worker进程结束时调用
		serv->onWorkerStop(serv, worker_pti);
	}
	swTrace("[Worker]max request\n");
	return SW_OK;
}
Beispiel #16
0
//create worker child proccess
static int swFactoryProcess_manager_start(swFactory *factory)
{
	swFactoryProcess *object = factory->object;
	int i, pid, ret;
	int writer_pti;

	swServer *serv = factory->ptr;

#if SW_WORKER_IPC_MODE == 2
#define _SW_PATH_BUF_LEN   128
	//这里使用ftok来获取消息队列的key
	char path_buf[_SW_PATH_BUF_LEN];
	char *path_ptr = getcwd(path_buf, _SW_PATH_BUF_LEN);
	//读数据队列
	if(swQueueMsg_create(&object->rd_queue, 1, ftok(path_ptr, 1), 1) < 0)
	{
		swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno);
		return SW_ERR;
	}
	//为TCP创建写队列
	if (serv->have_tcp_sock == 1)
	{
		//写数据队列
		if(swQueueMsg_create(&object->wt_queue, 1, ftok(path_ptr, 2), 1) < 0)
		{
			swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno);
			return SW_ERR;
		}
	}
#else
	object->pipes = sw_calloc(object->worker_num, sizeof(swPipe));
	if (object->pipes == NULL)
	{
		swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno);
		return SW_ERR;
	}
	//worker进程的pipes
	for (i = 0; i < object->worker_num; i++)
	{
		if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0)
		{
			swError("create unix socket[1] fail");
			return SW_ERR;
		}
		object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1);
		object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0);
	}
#endif
	if (serv->task_worker_num > 0)
	{
		if (swProcessPool_create(&SwooleG.task_workers, serv->task_worker_num, serv->max_request)< 0)
		{
			swWarn("[Master] create task_workers fail");
			return SW_ERR;
		}
		//设置指针和回调函数
		SwooleG.task_workers.ptr = serv;
		SwooleG.task_workers.onTask = swTaskWorker_onTask;
	}
	pid = fork();
	switch (pid)
	{
	//创建manager进程
	case 0:
		for (i = 0; i < object->worker_num; i++)
		{
//			close(worker_pipes[i].pipes[0]);
			writer_pti = (i % object->writer_num);
			object->workers[i].writer_id = writer_pti;
			pid = swFactoryProcess_worker_spawn(factory, i);
			if (pid < 0)
			{
				swError("Fork worker process fail");
				return SW_ERR;
			}
			else
			{
				object->workers[i].pid = pid;
			}
		}
		//创建task_worker进程
		if (serv->task_worker_num > 0)
		{
			swProcessPool_start(&SwooleG.task_workers);
		}
		//标识为管理进程
		SwooleG.process_type = SW_PROCESS_MANAGER;
		ret = swFactoryProcess_manager_loop(factory);
		exit(ret);
		break;
		//主进程
	default:
		object->manager_pid = pid;
		//TCP需要writer线程
		if (serv->have_tcp_sock == 1)
		{
			int ret = swFactoryProcess_writer_start(factory);
			if (ret < 0)
			{
				return SW_ERR;
			}
		}
#if SW_WORKER_IPC_MODE != 2
		for (i = 0; i < object->worker_num; i++)
		{
			writer_pti = (i % object->writer_num);
			object->workers[i].writer_id = writer_pti;

			if (serv->have_tcp_sock == 1)
			{
				//将写pipe设置到writer的reactor中
				object->writers[writer_pti].reactor.add(&(object->writers[writer_pti].reactor),
						object->workers[i].pipe_master, SW_FD_PIPE);
			}
		}
#endif
		break;
	case -1:
		swError("[swFactoryProcess_worker_start]fork manager process fail\n");
		return SW_ERR;
	}
	return SW_OK;
}
Beispiel #17
0
static int swFactoryProcess_manager_loop(swFactory *factory)
{
	int pid, new_pid;
	int i, writer_pti;
	int reload_worker_i = 0;
	int ret;

	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;
	swWorker *reload_workers;

	reload_workers = sw_calloc(object->worker_num, sizeof(swWorker));
	if (reload_workers == NULL)
	{
		swError("[manager] malloc[reload_workers] fail.\n");
		return SW_ERR;
	}

	//for reload
	swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0);

	while (swoole_running > 0)
	{
		pid = wait(NULL);
		swTrace("[manager] worker stop.pid=%d\n", pid);
		if (pid < 0)
		{
			if (manager_worker_reloading == 0)
			{
				swTrace("[Manager] wait fail. Error: %s [%d]", strerror(errno), errno);
			}
			else if (manager_reload_flag == 0)
			{
				memcpy(reload_workers, object->workers, sizeof(swWorker) * object->worker_num);
				manager_reload_flag = 1;
				goto kill_worker;
			}
		}
		if (swoole_running == 1)
		{
			for (i = 0; i < object->worker_num; i++)
			{
				//对比pid
				if (pid != object->workers[i].pid)
				{
					continue;
				}
				else
				{
					pid = 0;
					new_pid = swFactoryProcess_worker_spawn(factory, i);
					if (new_pid < 0)
					{
						swWarn("Fork worker process fail. Error: %s [%d]", strerror(errno), errno);
						return SW_ERR;
					}
					else
					{
						object->workers[i].pid = new_pid;
					}
				}
			}

			//task worker
			if(pid > 0)
			{
				swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid);
				if (exit_worker != NULL)
				{
					swProcessPool_spawn(&SwooleG.task_workers, exit_worker);
				}
			}
		}
		//reload worker
		kill_worker: if (manager_worker_reloading == 1)
		{
			//reload finish
			if (reload_worker_i >= object->worker_num)
			{
				manager_worker_reloading = 0;
				reload_worker_i = 0;
				continue;
			}
			ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
			if (ret < 0)
			{
				swWarn("[Manager]kill fail.pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno);
				continue;
			}
			reload_worker_i++;
		}
	}
	sw_free(reload_workers);
	return SW_OK;
}
Beispiel #18
0
void swoole_init(void)
{
    struct rlimit rlmt;
    if (SwooleG.running)
    {
        return;
    }

    bzero(&SwooleG, sizeof(SwooleG));
    bzero(&SwooleWG, sizeof(SwooleWG));
    bzero(sw_error, SW_ERROR_MSG_SIZE);

    SwooleG.running = 1;
    sw_errno = 0;

    SwooleG.log_fd = STDOUT_FILENO;
    SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
    SwooleG.pagesize = getpagesize();
    SwooleG.pid = getpid();
    SwooleG.socket_buffer_size = SW_SOCKET_BUFFER_SIZE;

    //get system uname
    uname(&SwooleG.uname);

    //random seed
    srandom(time(NULL));

    //init global shared memory
    SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1);
    if (SwooleG.memory_pool == NULL)
    {
        printf("[Master] Fatal Error: create global memory failed.");
        exit(1);
    }
    SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS));
    if (SwooleGS == NULL)
    {
        printf("[Master] Fatal Error: alloc memory for SwooleGS failed.");
        exit(2);
    }

    //init global lock
    swMutex_create(&SwooleGS->lock, 1);
    swMutex_create(&SwooleGS->lock_2, 1);

    if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0)
    {
        swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno);
        SwooleG.max_sockets = 1024;
    }
    else
    {
        SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur;
    }

    SwooleG.module_stack = swString_new(8192);
    if (SwooleG.module_stack == NULL)
    {
        exit(3);
    }

    if (!SwooleG.task_tmpdir)
    {
        SwooleG.task_tmpdir = strndup(SW_TASK_TMP_FILE, sizeof(SW_TASK_TMP_FILE));
        SwooleG.task_tmpdir_len = sizeof(SW_TASK_TMP_FILE);
    }

    char *tmp_dir = swoole_dirname(SwooleG.task_tmpdir);
    //create tmp dir
    if (access(tmp_dir, R_OK) < 0 && swoole_mkdir_recursive(tmp_dir) < 0)
    {
        swWarn("create task tmp dir(%s) failed.", tmp_dir);
    }
    if (tmp_dir)
    {
        sw_strdup_free(tmp_dir);
    }

    //init signalfd
#ifdef HAVE_SIGNALFD
    swSignalfd_init();
    SwooleG.use_signalfd = 1;
#endif
    //timerfd
#ifdef HAVE_TIMERFD
    SwooleG.use_timerfd = 1;
#endif

    SwooleG.use_timer_pipe = 1;

    SwooleStats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats));
    if (SwooleStats == NULL)
    {
        swError("[Master] Fatal Error: alloc memory for SwooleStats failed.");
    }
    swoole_update_time();
}
Beispiel #19
0
/**
 * worker main loop
 */
int swWorker_loop(swFactory *factory, int worker_id)
{
    swServer *serv = factory->ptr;

#ifndef SW_WORKER_USE_SIGNALFD
    SwooleG.use_signalfd = 0;
#elif defined(HAVE_SIGNALFD)
    SwooleG.use_signalfd = 1;
#endif
    //timerfd
#ifdef HAVE_TIMERFD
    SwooleG.use_timerfd = 1;
#endif

    //worker_id
    SwooleWG.id = worker_id;
    SwooleWG.request_count = 0;
    SwooleG.pid = getpid();

    //signal init
    swWorker_signal_init();
    swWorker *worker = swServer_get_worker(serv, worker_id);
    swServer_worker_init(serv, worker);

    SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
    if (SwooleG.main_reactor == NULL)
    {
        swError("[Worker] malloc for reactor failed.");
        return SW_ERR;
    }

    if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0)
    {
        swError("[Worker] create worker_reactor failed.");
        return SW_ERR;
    }
    
    serv->workers[worker_id].status = SW_WORKER_IDLE;

    int pipe_worker = serv->workers[worker_id].pipe_worker;

    swSetNonBlock(pipe_worker);
    SwooleG.main_reactor->ptr = serv;
    SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite);

    /**
     * set pipe buffer size
     */
    int i;
    swConnection *pipe_socket;
    for (i = 0; i < serv->worker_num + SwooleG.task_worker_num; i++)
    {
        worker = swServer_get_worker(serv, i);
        pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_master);
        pipe_socket->buffer_size = serv->pipe_buffer_size;
        pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_worker);
        pipe_socket->buffer_size = serv->pipe_buffer_size;
    }

    swWorker_onStart(serv);

#ifdef HAVE_SIGNALFD
    if (SwooleG.use_signalfd)
    {
        swSignalfd_setup(SwooleG.main_reactor);
    }
#endif
    //main loop
    SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL);
    //clear pipe buffer
    swWorker_clean();
    //worker shutdown
    swWorker_onStop(serv);
    return SW_OK;
}
Beispiel #20
0
/**
 * worker main loop
 */
static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti)
{
	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;

	struct
	{
		long pti;
		swEventData req;
	} rdata;
	int n;

	int pipe_rd = object->workers[worker_pti].pipe_worker;

#ifdef HAVE_CPU_AFFINITY
	if (serv->open_cpu_affinity == 1)
	{
		cpu_set_t cpu_set;
		CPU_ZERO(&cpu_set);
		CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set);
		if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set))
		{
			swWarn("pthread_setaffinity_np set failed");
		}
	}
#endif

	//signal init
	swFactoryProcess_worker_signal_init();

	//worker_id
	SwooleWG.id = worker_pti;

#ifndef SW_USE_RINGBUFFER
	int i;
	//for open_check_eof and  open_check_length
	if (serv->open_eof_check || serv->open_length_check)
	{
		SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num);
		if (SwooleWG.buffer_input == NULL)
		{
			swError("malloc for SwooleWG.buffer_input failed.");
			return SW_ERR;
		}
		for (i = 0; i < serv->reactor_num; i++)
		{
			SwooleWG.buffer_input[i] = swString_new(serv->buffer_input_size);
			if (SwooleWG.buffer_input[i] == NULL)
			{
				swError("buffer_input init failed.");
				return SW_ERR;
			}
		}
	}
#endif

	if (serv->ipc_mode == SW_IPC_MSGQUEUE)
	{
		//抢占式,使用相同的队列type
		if (serv->dispatch_mode == SW_DISPATCH_QUEUE)
		{
			//这里必须加1
			rdata.pti = serv->worker_num + 1;
		}
		else
		{
			//必须加1
			rdata.pti = worker_pti + 1;
		}
	}
	else
	{
		SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
		if (SwooleG.main_reactor == NULL)
		{
			swError("[Worker] malloc for reactor failed.");
			return SW_ERR;
		}
		if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0)
		{
			swError("[Worker] create worker_reactor failed.");
			return SW_ERR;
		}
		swSetNonBlock(pipe_rd);
		SwooleG.main_reactor->ptr = serv;
		SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE);
		SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive);

#ifdef HAVE_SIGNALFD
		if (SwooleG.use_signalfd)
		{
			swSignalfd_setup(SwooleG.main_reactor);
		}
#endif

	}

	if (factory->max_request < 1)
	{
		worker_task_always = 1;
	}
	else
	{
		worker_task_num = factory->max_request;
		worker_task_num += swRandom(worker_pti);
	}

	//worker start
	if (serv->onWorkerStart != NULL)
	{
		serv->onWorkerStart(serv, worker_pti);
	}

	if (serv->ipc_mode == SW_IPC_MSGQUEUE)
	{
		while (SwooleG.running > 0)
		{
			n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req));
			if (n < 0)
			{
				if (errno == EINTR)
				{
					if (SwooleG.signal_alarm && serv->onTimer)
					{
						swTimer_select(&SwooleG.timer);
						SwooleG.signal_alarm = 0;
					}
				}
				else
				{
					swWarn("[Worker]rd_queue[%ld]->out wait failed. Error: %s [%d]", rdata.pti, strerror(errno), errno);
				}
				continue;
			}
			swFactoryProcess_worker_excute(factory, &rdata.req);
		}
	}
	else
	{
		struct timeval timeo;
		timeo.tv_sec = SW_REACTOR_TIMEO_SEC;
		timeo.tv_usec = SW_REACTOR_TIMEO_USEC;
		SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo);
	}

	if (serv->onWorkerStop != NULL)
	{
		//worker shutdown
		serv->onWorkerStop(serv, worker_pti);
	}
	swTrace("[Worker]max request");
	return SW_OK;
}
Beispiel #21
0
int swTimer_start(swTimer *timer, int interval_ms)
{
	struct timeval now;
	if (gettimeofday(&now, NULL) < 0)
	{
		swWarn("malloc fail\n");
		return SW_ERR;
	}
	timer->interval_ms = interval_ms;
	timer->lasttime = interval_ms;

	int sec = interval_ms / 1000;
	int msec = (((float) interval_ms / 1000) - sec) * 1000;
#ifdef HAVE_TIMERFD
	struct itimerspec timer_set;
	memset(&timer_set, 0, sizeof(timer_set));
	timer->fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
	if (timer->fd < 0)
	{
		swError("create timerfd fail\n");
		return SW_ERR;
	}
	timer_set.it_value.tv_sec = now.tv_sec + sec;
	timer_set.it_value.tv_nsec = now.tv_usec + msec * 1000;
	timer_set.it_interval.tv_sec = sec;
	timer_set.it_interval.tv_nsec = msec * 1000 * 1000;
	if (timerfd_settime(timer->fd, TFD_TIMER_ABSTIME, &timer_set, NULL) == -1)
	{
		swWarn("set timer fail\n");
		return SW_ERR;
	}
	timer->use_pipe = 0;
#else
	struct itimerval timer_set;
	int ret;
	//eventfd是2.6.26提供的,timerfd是2.6.27提供的
#ifdef HAVE_EVENTFD
	ret = swPipeEventfd_create(&timer->pipe, 0, 0);
#else
	ret = swPipeBase_create(&timer->pipe, 0);
#endif
	if (ret < 0)
	{
		swWarn("create timer pipe fail");
		return SW_ERR;
	}
	memset(&timer_set, 0, sizeof(timer_set));
	timer_set.it_value.tv_sec = sec;
	timer_set.it_value.tv_usec = msec * 1000;
	timer_set.it_interval.tv_sec = sec;
	timer_set.it_interval.tv_usec = msec * 1000;
	if (setitimer(ITIMER_REAL, &timer_set, NULL) < 0)
	{
		swWarn("set timer fail");
		return SW_ERR;
	}
	timer->fd = timer->pipe.getFd(&timer->pipe, 0);
	timer->use_pipe = 1;
#endif
	return SW_OK;
}
Beispiel #22
0
static int swFactoryProcess_manager_loop(swFactory *factory)
{
	int pid, new_pid;
	int i;
	int reload_worker_i = 0;
	int ret;
	int worker_exit_code;

	SwooleG.use_signalfd = 0;
	SwooleG.use_timerfd = 0;

	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;
	swWorker *reload_workers;

	if (serv->onManagerStart)
	{
		serv->onManagerStart(serv);
	}

	reload_workers = sw_calloc(serv->worker_num, sizeof(swWorker));
	if (reload_workers == NULL)
	{
		swError("[manager] malloc[reload_workers] failed");
		return SW_ERR;
	}

	//for reload
	swSignal_add(SIGUSR1, swManagerSignalHanlde);

	while (SwooleG.running > 0)
	{
		pid = wait(&worker_exit_code);
		swTrace("[manager] worker stop.pid=%d\n", pid);
		if (pid < 0)
		{
			if (manager_worker_reloading == 0)
			{
				swTrace("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno);
			}
			else if (manager_reload_flag == 0)
			{
				memcpy(reload_workers, object->workers, sizeof(swWorker) * serv->worker_num);
				manager_reload_flag = 1;
				goto kill_worker;
			}
		}
		if (SwooleG.running == 1)
		{
			for (i = 0; i < serv->worker_num; i++)
			{
				//对比pid
				if (pid != object->workers[i].pid)
				{
					continue;
				}
				else
				{
					if(serv->onWorkerError!=NULL && WEXITSTATUS(worker_exit_code) > 0)
					{
						serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code));
					}
					pid = 0;
					new_pid = swFactoryProcess_worker_spawn(factory, i);
					if (new_pid < 0)
					{
						swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno);
						return SW_ERR;
					}
					else
					{
						object->workers[i].pid = new_pid;
					}
				}
			}

			//task worker
			if(pid > 0)
			{
				swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid);
				if (exit_worker != NULL)
				{
					swProcessPool_spawn(exit_worker);
				}
			}
		}
		//reload worker
		kill_worker: if (manager_worker_reloading == 1)
		{
			//reload finish
			if (reload_worker_i >= serv->worker_num)
			{
				manager_worker_reloading = 0;
				reload_worker_i = 0;
				continue;
			}
			ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
			if (ret < 0)
			{
				swWarn("[Manager]kill failed, pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno);
				continue;
			}
			reload_worker_i++;
		}
	}
	sw_free(reload_workers);
	if (serv->onManagerStop)
	{
		serv->onManagerStop(serv);
	}
	return SW_OK;
}
Beispiel #23
0
void swoole_init(void)
{
    struct rlimit rlmt;
    if (SwooleG.running)
    {
        return;
    }

    bzero(&SwooleG, sizeof(SwooleG));
    bzero(&SwooleWG, sizeof(SwooleWG));
    bzero(sw_error, SW_ERROR_MSG_SIZE);

    SwooleG.running = 1;
    sw_errno = 0;

    SwooleG.log_fd = STDOUT_FILENO;
    SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
    SwooleG.pagesize = getpagesize();
    SwooleG.pid = getpid();

    //get system uname
    uname(&SwooleG.uname);

    //random seed
    srandom(time(NULL));

    //init global shared memory
    SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1);
    if (SwooleG.memory_pool == NULL)
    {
        printf("[Master] Fatal Error: create global memory failed.");
        exit(1);
    }
    SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS));
    if (SwooleGS == NULL)
    {
        printf("[Master] Fatal Error: alloc memory for SwooleGS failed.");
        exit(2);
    }

    //init global lock
    swMutex_create(&SwooleGS->lock, 1);
    swMutex_create(&SwooleGS->lock_2, 1);

    if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0)
    {
        swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno);
        SwooleG.max_sockets = 1024;
    }
    else
    {
        SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur;
    }

    //init signalfd
#ifdef HAVE_SIGNALFD
    swSignalfd_init();
    SwooleG.use_signalfd = 1;
#endif
    //timerfd
#ifdef HAVE_TIMERFD
    SwooleG.use_timerfd = 1;
#endif

    SwooleG.use_timer_pipe = 1;

    SwooleStats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats));
    if (SwooleStats == NULL)
    {
        swError("[Master] Fatal Error: alloc memory for SwooleStats failed.");
    }
    swoole_update_time();
}
Beispiel #24
0
/**
 * worker main loop
 */
int swWorker_loop(swFactory *factory, int worker_id)
{
    swServer *serv = factory->ptr;

#ifndef SW_WORKER_USE_SIGNALFD
    SwooleG.use_signalfd = 0;
#endif

    //worker_id
    SwooleWG.id = worker_id;
    SwooleG.pid = getpid();

    //signal init
    swWorker_signal_init();
    swWorker *worker = swServer_get_worker(serv, worker_id);
    swServer_worker_init(serv, worker);

    SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
    if (SwooleG.main_reactor == NULL)
    {
        swError("[Worker] malloc for reactor failed.");
        return SW_ERR;
    }

    if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0)
    {
        swError("[Worker] create worker_reactor failed.");
        return SW_ERR;
    }

    int pipe_worker = serv->workers[worker_id].pipe_worker;

    swSetNonBlock(pipe_worker);
    SwooleG.main_reactor->ptr = serv;
    SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
    SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_FD_WRITE, swReactor_onWrite);

    if (serv->max_request < 1)
    {
        SwooleWG.run_always = 1;
    }
    else
    {
        worker_task_num = serv->max_request;
        if (worker_task_num > 10)
        {
            worker_task_num += swRandom(worker_id);
        }
    }

    swWorker_onStart(serv);

#ifdef HAVE_SIGNALFD
    if (SwooleG.use_signalfd)
    {
        swSignalfd_setup(SwooleG.main_reactor);
    }
#endif
    SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL);

    swWorker_onStop(serv);
    return SW_OK;
}
Beispiel #25
0
static int swFactoryProcess_manager_loop(swFactory *factory)
{
	int pid, new_pid;
	int i, writer_pti;
	int reload_worker_i = 0;
	int ret;

	swFactoryProcess *this = factory->object;
	swWorkerChild *reload_workers;

	reload_workers = sw_calloc(this->worker_num, sizeof(swWorkerChild));
	if (reload_workers == NULL )
	{
		swError("[manager] malloc[reload_workers] fail.\n");
		return SW_ERR;
	}

	//for reload
	swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0);

	while (1)
	{
		pid = wait(NULL );
		swTrace("[manager] worker stop.pid=%d\n", pid);
		if (pid < 0)
		{
			if (manager_worker_reloading == 0)
			{
				swTrace("wait fail.errno=%d\n", errno);
			}
			else if (manager_reload_flag == 0)
			{
				memcpy(reload_workers, this->workers, sizeof(swWorkerChild) * this->worker_num);
				manager_reload_flag = 1;
				goto kill_worker;
			}
		}

		for (i = 0; i < this->worker_num; i++)
		{

			if (pid != this->workers[i].pid)
				continue;

			writer_pti = (i % this->writer_num);
			new_pid = swFactoryProcess_worker_spawn(factory, writer_pti, i);
			if (new_pid < 0)
			{
				swWarn("Fork worker process fail.Errno=%d\n", errno);
				return SW_ERR;
			}
			else
			{
				this->workers[i].pid = new_pid;
			}
		}

		//reload worker
		kill_worker: if (manager_worker_reloading == 1)
		{
			//reload finish
			if (reload_worker_i >= this->worker_num)
			{
				manager_worker_reloading = 0;
				reload_worker_i = 0;
				continue;
			}
			ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
			if (ret < 0)
			{
				swWarn("kill fail.pid=%d|errno=%d\n", reload_workers[reload_worker_i].pid, errno);
				continue;
			}
			reload_worker_i++;
		}
	}
	return SW_OK;
}
Beispiel #26
0
int swProcessPool_wait(swProcessPool *pool)
{
	int pid, new_pid;
	int reload_worker_i = 0;
	int ret, i;

	swWorker *reload_workers;
	reload_workers = sw_calloc(pool->worker_num, sizeof(swWorker));
	if (reload_workers == NULL)
	{
		swError("[manager] malloc[reload_workers] fail.\n");
		return SW_ERR;
	}

	while (1)
	{
		pid = wait(NULL);
		swTrace("[manager] worker stop.pid=%d\n", pid);
		if (pid < 0)
		{
			if (pool->reloading == 0)
			{
				swTrace("[Manager] wait fail. Error: %s [%d]", strerror(errno), errno);
			}
			else if (pool->reload_flag == 0)
			{
				memcpy(reload_workers, pool->workers, sizeof(swWorker) * pool->worker_num);
				pool->reload_flag = 1;
				goto reload_worker;
			}
		}
		if (SwooleG.running == 1)
		{
			swWorker *exit_worker = swHashMap_find_int(&pool->map, pid);
			if (exit_worker == NULL)
			{
				swWarn("[Manager]unknow worker[pid=%d]", pid);
				continue;
			}
			new_pid = swProcessPool_spawn(exit_worker);
			if (new_pid < 0)
			{
				swWarn("Fork worker process fail. Error: %s [%d]", strerror(errno), errno);
				return SW_ERR;
			}
			swHashMap_del_int(&pool->map, pid);
		}
		//reload worker
		reload_worker: if (pool->reloading == 1)
		{
			//reload finish
			if (reload_worker_i >= pool->worker_num)
			{
				pool->reloading = 0;
				reload_worker_i = 0;
				continue;
			}
			ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
			if (ret < 0)
			{
				swWarn("[Manager]kill fail.pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid,
						strerror(errno), errno);
				continue;
			}
			reload_worker_i++;
		}
	}
	return SW_OK;
}
Beispiel #27
0
//create worker child proccess
static int swFactoryProcess_manager_start(swFactory *factory)
{
	swFactoryProcess *object = factory->object;
	int i, pid, ret;
	int reactor_pti;
	swServer *serv = factory->ptr;

	if (serv->ipc_mode == SW_IPC_MSGQUEUE)
	{
		//读数据队列
		if (swQueueMsg_create(&object->rd_queue, 1, serv->message_queue_key, 1) < 0)
		{
			swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno);
			return SW_ERR;
		}
		//为TCP创建写队列
		if (serv->have_tcp_sock == 1)
		{
			//写数据队列
			if (swQueueMsg_create(&object->wt_queue, 1, serv->message_queue_key + 1, 1) < 0)
			{
				swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno);
				return SW_ERR;
			}
		}
	}
	else
	{
		object->pipes = sw_calloc(serv->worker_num, sizeof(swPipe));
		if (object->pipes == NULL)
		{
			swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno);
			return SW_ERR;
		}
		//worker进程的pipes
		for (i = 0; i < serv->worker_num; i++)
		{
			if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0)
			{
				swError("create unix socket[1] fail");
				return SW_ERR;
			}
			object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1);
			object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0);
		}
	}


	if (SwooleG.task_worker_num > 0)
	{
		key_t msgqueue_key = 0;
		if (SwooleG.task_ipc_mode > 0)
		{
			msgqueue_key =  serv->message_queue_key + 2;
		}
		if (swProcessPool_create(&SwooleG.task_workers, SwooleG.task_worker_num, serv->max_request, msgqueue_key)< 0)
		{
			swWarn("[Master] create task_workers fail");
			return SW_ERR;
		}
		//设置指针和回调函数
		SwooleG.task_workers.ptr = serv;
		SwooleG.task_workers.onTask = swTaskWorker_onTask;
		if (serv->onWorkerStart != NULL)
		{
			SwooleG.task_workers.onWorkerStart = swTaskWorker_onWorkerStart;
		}
	}
	pid = fork();
	switch (pid)
	{
	//创建manager进程
	case 0:
		//创建子进程
		for (i = 0; i < serv->worker_num; i++)
		{
			//close(worker_pipes[i].pipes[0]);
			reactor_pti = (i % serv->writer_num);
			object->workers[i].reactor_id = reactor_pti;
			pid = swFactoryProcess_worker_spawn(factory, i);
			if (pid < 0)
			{
				swError("Fork worker process fail");
				return SW_ERR;
			}
			else
			{
				object->workers[i].pid = pid;
			}
		}
		/**
		 * create task worker pool
		 */
		if (SwooleG.task_worker_num > 0)
		{
			swProcessPool_start(&SwooleG.task_workers);
		}
		//标识为管理进程
		SwooleG.process_type = SW_PROCESS_MANAGER;
		ret = swFactoryProcess_manager_loop(factory);
		exit(ret);
		break;
		//主进程
	default:
		SwooleGS->manager_pid = pid;
		break;
	case -1:
		swError("[swFactoryProcess_worker_start]fork manager process fail");
		return SW_ERR;
	}
	return SW_OK;
}
Beispiel #28
0
/**
 * worker main loop
 */
int swWorker_loop(swFactory *factory, int worker_id)
{
    swServer *serv = factory->ptr;

    struct
    {
        long pti;
        swEventData req;
    } rdata;
    int n;

#ifdef HAVE_CPU_AFFINITY
    if (serv->open_cpu_affinity == 1)
    {
        cpu_set_t cpu_set;
        CPU_ZERO(&cpu_set);
        CPU_SET(worker_id % SW_CPU_NUM, &cpu_set);
        if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set))
        {
            swWarn("pthread_setaffinity_np set failed");
        }
    }
#endif

#ifndef SW_WORKER_USE_SIGNALFD
    SwooleG.use_signalfd = 0;
#endif

    //signal init
    swWorker_signal_init();

    //worker_id
    SwooleWG.id = worker_id;

    int i;

    SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num);

    if (SwooleWG.buffer_input == NULL)
    {
        swError("malloc for SwooleWG.buffer_input failed.");
        return SW_ERR;
    }

#ifndef SW_USE_RINGBUFFER
    int buffer_input_size;
    if (serv->open_eof_check || serv->open_length_check || serv->open_http_protocol)
    {
        buffer_input_size = serv->package_max_length;
    }
    else
    {
        buffer_input_size = SW_BUFFER_SIZE_BIG;
    }

    for (i = 0; i < serv->reactor_num; i++)
    {
        SwooleWG.buffer_input[i] = swString_new(buffer_input_size);
        if (SwooleWG.buffer_input[i] == NULL)
        {
            swError("buffer_input init failed.");
            return SW_ERR;
        }
    }
#endif

    if (serv->ipc_mode == SW_IPC_MSGQUEUE)
    {
        //抢占式,使用相同的队列type
        if (serv->dispatch_mode == SW_DISPATCH_QUEUE)
        {
            //这里必须加1
            rdata.pti = serv->worker_num + 1;
        }
        else
        {
            //必须加1
            rdata.pti = worker_id + 1;
        }
    }
    else
    {
        SwooleG.main_reactor = sw_malloc(sizeof(swReactor));
        if (SwooleG.main_reactor == NULL)
        {
            swError("[Worker] malloc for reactor failed.");
            return SW_ERR;
        }
        if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0)
        {
            swError("[Worker] create worker_reactor failed.");
            return SW_ERR;
        }

        int pipe_worker = serv->workers[worker_id].pipe_worker;

        swSetNonBlock(pipe_worker);
        SwooleG.main_reactor->ptr = serv;
        SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE);
        SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive);
        SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_EVENT_WRITE, swPipeUnsock_onWrite);
    }

    if (serv->max_request < 1)
    {
        SwooleWG.run_always = 1;
    }
    else
    {
        worker_task_num = serv->max_request;
        worker_task_num += swRandom(worker_id);
    }

    swWorker_onStart(serv);

    if (serv->ipc_mode == SW_IPC_MSGQUEUE)
    {
        while (SwooleG.running > 0)
        {
            n = serv->read_queue.out(&serv->read_queue, (swQueue_data *) &rdata, sizeof(rdata.req));
            if (n < 0)
            {
                if (errno == EINTR)
                {
                    if (SwooleG.signal_alarm)
                    {
                        SwooleG.timer.select(&SwooleG.timer);
                    }
                }
                else
                {
                    swWarn("[Worker%ld] read_queue->out() failed. Error: %s [%d]", rdata.pti, strerror(errno), errno);
                }
                continue;
            }
            swWorker_excute(factory, &rdata.req);
        }
    }
    else
    {
#ifdef HAVE_SIGNALFD
        if (SwooleG.use_signalfd)
        {
            swSignalfd_setup(SwooleG.main_reactor);
        }
#endif
        SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL);
    }

    swWorker_onStop(serv);
    return SW_OK;
}
Beispiel #29
0
int swProcessPool_wait(swProcessPool *pool)
{
    int pid, new_pid;
    int reload_worker_i = 0;
    int ret;
    int status;

    swWorker *reload_workers;
    reload_workers = sw_calloc(pool->worker_num, sizeof(swWorker));
    if (reload_workers == NULL)
    {
        swError("[manager] malloc[reload_workers] fail.\n");
        return SW_ERR;
    }

    while (SwooleG.running)
    {
        pid = wait(&status);
        if (pid < 0)
        {
            if (pool->reloading == 0)
            {
                swTrace("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno);
            }
            else if (pool->reload_flag == 0)
            {
                swTrace("[Manager] reload workers.");
                memcpy(reload_workers, pool->workers, sizeof(swWorker) * pool->worker_num);
                pool->reload_flag = 1;
                goto reload_worker;
            }
            else if (SwooleG.running == 0)
            {
                break;
            }
        }
        swTrace("[Manager] worker stop.pid=%d", pid);
        if (SwooleG.running == 1)
        {
            swWorker *exit_worker = swHashMap_find_int(pool->map, pid);
            if (exit_worker == NULL)
            {
                if (pool->onWorkerNotFound)
                {
                    pool->onWorkerNotFound(pool, pid, status);
                }
                else
                {
                    swWarn("[Manager]unknow worker[pid=%d]", pid);
                }
                continue;
            }
            if (!WIFEXITED(status))
            {
                swWarn("worker#%d abnormal exit, status=%d, signal=%d", exit_worker->id, WEXITSTATUS(status),  WTERMSIG(status));
            }
            new_pid = swProcessPool_spawn(exit_worker);
            if (new_pid < 0)
            {
                swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno);
                sw_free(reload_workers);
                return SW_ERR;
            }
            swHashMap_del_int(pool->map, pid);
        }
        //reload worker
        reload_worker:
        if (pool->reloading == 1)
        {
            //reload finish
            if (reload_worker_i >= pool->worker_num)
            {
                pool->reloading = 0;
                reload_worker_i = 0;
                continue;
            }
            ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
            if (ret < 0)
            {
                swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid);
                continue;
            }
            reload_worker_i++;
        }
    }
    sw_free(reload_workers);
    return SW_OK;
}
Beispiel #30
0
static int swFactoryProcess_manager_loop(swFactory *factory)
{
    int pid, new_pid;
    int i;
    int reload_worker_i = 0;
    int reload_worker_num;
    int ret;
    int worker_exit_code;

    SwooleG.use_signalfd = 0;
    SwooleG.use_timerfd = 0;

    memset(&ManagerProcess, 0, sizeof(ManagerProcess));

    swServer *serv = factory->ptr;
    swWorker *reload_workers;

    if (serv->onManagerStart)
    {
        serv->onManagerStart(serv);
    }

    reload_worker_num = serv->worker_num + SwooleG.task_worker_num;
    reload_workers = sw_calloc(reload_worker_num, sizeof(swWorker));
    if (reload_workers == NULL)
    {
        swError("malloc[reload_workers] failed");
        return SW_ERR;
    }

    //for reload
    swSignal_add(SIGTERM, swManager_signal_handle);
    swSignal_add(SIGUSR1, swManager_signal_handle);
    swSignal_add(SIGUSR2, swManager_signal_handle);
    //swSignal_add(SIGINT, swManager_signal_handle);

    while (SwooleG.running > 0)
    {
        pid = wait(&worker_exit_code);

        if (pid < 0)
        {
            if (ManagerProcess.reloading == 0)
            {
                swTrace("wait() failed. Error: %s [%d]", strerror(errno), errno);
            }
            else if (ManagerProcess.reload_event_worker == 1)
            {
                memcpy(reload_workers, serv->workers, sizeof(swWorker) * serv->worker_num);
                reload_worker_num = serv->worker_num;
                if (SwooleG.task_worker_num > 0)
                {
                    memcpy(reload_workers + serv->worker_num, SwooleG.task_workers.workers,
                            sizeof(swWorker) * SwooleG.task_worker_num);
                    reload_worker_num += SwooleG.task_worker_num;
                }
                reload_worker_i = 0;
                ManagerProcess.reload_event_worker = 0;
                goto kill_worker;
            }
            else if (ManagerProcess.reload_task_worker == 1)
            {
                if (SwooleG.task_worker_num == 0)
                {
                    swWarn("Cannot reload workers, because server no have task workers.");
                    continue;
                }
                memcpy(reload_workers, SwooleG.task_workers.workers, sizeof(swWorker) * SwooleG.task_worker_num);
                reload_worker_num = SwooleG.task_worker_num;
                reload_worker_i = 0;
                ManagerProcess.reload_task_worker = 0;
                goto kill_worker;
            }
        }
        if (SwooleG.running == 1)
        {
            for (i = 0; i < serv->worker_num; i++)
            {
                //compare PID
                if (pid != serv->workers[i].pid)
                {
                    continue;
                }
                else
                {
                    if (serv->onWorkerError != NULL && WEXITSTATUS(worker_exit_code) > 0)
                    {
                        serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code));
                    }
                    pid = 0;
                    while (1)
                    {
                        new_pid = swFactoryProcess_worker_spawn(factory, i);
                        if (new_pid < 0)
                        {
                            usleep(100000);
                            continue;
                        }
                        else
                        {
                            serv->workers[i].pid = new_pid;
                            break;
                        }
                    }
                }
            }

            //task worker
            if (pid > 0)
            {
                swWorker *exit_worker = swHashMap_find_int(SwooleG.task_workers.map, pid);
                if (exit_worker != NULL)
                {
                    swProcessPool_spawn(exit_worker);
                }
            }
        }
        //reload worker
        kill_worker:
        if (ManagerProcess.reloading == 1)
        {
            //reload finish
            if (reload_worker_i >= reload_worker_num)
            {
                ManagerProcess.reloading = 0;
                reload_worker_i = 0;
                continue;
            }
            ret = kill(reload_workers[reload_worker_i].pid, SIGTERM);
            if (ret < 0)
            {
                swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid);
                continue;
            }
            reload_worker_i++;
        }
    }

    sw_free(reload_workers);

    //kill all child process
    for (i = 0; i < serv->worker_num; i++)
    {
        swTrace("[Manager]kill worker processor");
        kill(serv->workers[i].pid, SIGTERM);
    }

    if (SwooleG.task_worker_num > 0)
    {
        swProcessPool_shutdown(&SwooleG.task_workers);
    }

    if (serv->onManagerStop)
    {
        serv->onManagerStop(serv);
    }
    return SW_OK;
}