Example #1
0
/**
 * Worker进程,向writer发送数据
 */
int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
	//UDP直接在worker进程内发送
	int ret, sendn, count, pipe_i;
	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;
	swReactor *reactor;
	int fd = resp->info.fd;

	//UDP在worker进程中直接发送到客户端
	if(resp->info.type == SW_EVENT_UDP)
	{
		ret = swServer_send_udp_packet(serv, resp);
		goto finish;
	}

	//swQueue_data for msg queue
	struct
	{
		long pti;
		swEventData _send;
	} sdata;

	//写队列mtype
	sdata.pti = (SwooleWG.id % serv->writer_num) + 1;

	//copy
	memcpy(sdata._send.data, resp->data, resp->info.len);

	swConnection *conn = swServer_get_connection(serv, fd);
	if(conn == NULL)
	{
		swWarn("connection[%d] not found.", fd);
		return SW_ERR;
	}

	sdata._send.info.fd = fd;
	sdata._send.info.type = resp->info.type;
	sdata._send.info.len = resp->info.len;
	sdata._send.info.from_id = conn->from_id;
	sendn = resp->info.len + sizeof(resp->info);

	//swWarn("send: type=%d|content=%s", resp->info.type, resp->data);
	swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, fd);

	for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++)
	{
#if SW_WORKER_IPC_MODE == 2
		ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn);
#else
		reactor = &(serv->reactor_threads[conn->from_id].reactor);
		if (serv->reactor_pipe_num > 1)
		{
			pipe_i = fd % serv->reactor_pipe_num + reactor->id;
		}
		else
		{
			pipe_i = reactor->id;
		}
		//swWarn("send to reactor. fd=%d|pipe_i=%d|reactor_id=%d|reactor_pipe_num=%d", fd, pipe_i, conn->from_id, serv->reactor_pipe_num);
		ret = write(object->workers[pipe_i].pipe_worker, &sdata._send, sendn);
#endif
		//printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno);
		if (ret >= 0)
		{
			break;
		}
		else if (errno == EINTR)
		{
			continue;
		}
		else if (errno == EAGAIN)
		{
			swYield();
		}
		else
		{
			break;
		}
	}
	finish:
	if (ret < 0)
	{
		swWarn("[Worker#%d]sendto writer pipe or queue failed. Error: %s [%d]", getpid(), strerror(errno), errno);
	}
	return ret;
}
Example #2
0
/**
 * Worker进程,向writer发送数据
 */
int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
	//UDP直接在worker进程内发送
	int ret, sendn, count;;
	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;

	//from_id超过serv->poll_thread_num,这是一个UDP
	//UDP在worker进程中直接发送到客户端
	if(resp->info.from_id >= serv->poll_thread_num)
	{
		ret = swServer_send_udp_packet(serv, resp);
		goto finish;
	}

	//swQueue_data for msg queue
	struct {
		long pti;
		swEventData _send;
	} sdata;

	//写队列mtype
	sdata.pti = (c_worker_pti % serv->writer_num) + 1;

	//copy
	memcpy(sdata._send.data, resp->data, resp->info.len);

	sdata._send.info.fd = resp->info.fd;
	sdata._send.info.len = resp->info.len;
	sdata._send.info.from_id = resp->info.from_id;
	sendn =  resp->info.len + sizeof(resp->info);

	swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, sdata._send.info.fd);

	for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++)
	{
#if SW_WORKER_IPC_MODE == 2
		ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn);
#else
		ret = write(object->workers[c_worker_pti].pipe_worker, &sdata._send, sendn);
#endif
		//printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno);
		if (ret >= 0)
		{
			break;
		}
		else if (errno == EINTR)
		{
			continue;
		}
		else if (errno == EAGAIN)
		{
			swYield();
		}
		else
		{
			break;
		}
	}
	finish:
	if (ret < 0)
	{
		swWarn("[Worker#%d]sendto writer pipe or queue fail. Error: %s [%d]", getpid(), strerror(errno), errno);
	}
	return ret;
}
Example #3
0
/**
 * worker: send to client
 */
int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
	int ret, sendn, count;
	swFactoryProcess *object = factory->object;
	swServer *serv = factory->ptr;
	int fd = resp->info.fd;

	//unix dgram
	if (resp->info.type == SW_EVENT_UNIX_DGRAM)
	{
		socklen_t len;
		struct sockaddr_un addr_un;
		int from_sock = resp->info.from_fd;

		addr_un.sun_family = AF_UNIX;
		memcpy(addr_un.sun_path, resp->sun_path, resp->sun_path_len);
		len = sizeof(addr_un);
		ret = swSendto(from_sock, resp->data, resp->info.len, 0, (struct sockaddr *) &addr_un, len);
		goto finish;
	}
	//UDP pacakge
	else if (resp->info.type == SW_EVENT_UDP || resp->info.type == SW_EVENT_UDP6)
	{
		ret = swServer_send_udp_packet(serv, resp);
		goto finish;
	}

	//swQueue_data for msg queue
	struct
	{
		long pti;
		swEventData _send;
	} sdata;

	//for message queue
	sdata.pti = (SwooleWG.id % serv->writer_num) + 1;

	//copy
	memcpy(sdata._send.data, resp->data, resp->info.len);

	swConnection *conn = swServer_get_connection(serv, fd);
	if (conn == NULL || conn->active == 0)
	{
		swWarn("connection[%d] not found.", fd);
		return SW_ERR;
	}

	sdata._send.info.fd = fd;
	sdata._send.info.type = resp->info.type;
	sdata._send.info.len = resp->info.len;
	sdata._send.info.from_id = conn->from_id;
	sendn = resp->info.len + sizeof(resp->info);

	//swWarn("send: type=%d|content=%s", resp->info.type, resp->data);
	swTrace("[Worker]wt_queue[%ld]->in| fd=%d", sdata.pti, fd);

	for (count = 0; count < SW_WORKER_SENDTO_COUNT; count++)
	{
		if (serv->ipc_mode == SW_IPC_MSGQUEUE)
		{
			ret = object->wt_queue.in(&object->wt_queue, (swQueue_data *)&sdata, sendn);
		}
		else
		{
			int pipe_i;
			swReactor *reactor = &(serv->reactor_threads[conn->from_id].reactor);
			if (serv->reactor_pipe_num > 1)
			{
				pipe_i = fd % serv->reactor_pipe_num + reactor->id;
			}
			else
			{
				pipe_i = reactor->id;
			}
			//swWarn("send to reactor. fd=%d|pipe_i=%d|reactor_id=%d|reactor_pipe_num=%d", fd, pipe_i, conn->from_id, serv->reactor_pipe_num);
			ret = write(object->workers[pipe_i].pipe_worker, &sdata._send, sendn);
		}
		//printf("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d\n", sdata._send.info.fd, sdata._send.info.from_id, sdata._send.data, ret, errno);
		if (ret >= 0)
		{
			break;
		}
		else if (errno == EINTR)
		{
			continue;
		}
		else if (errno == EAGAIN)
		{
			swYield();
		}
		else
		{
			break;
		}
	}
	finish:
	if (ret < 0)
	{
		swWarn("[Worker#%d]sendto writer pipe or queue failed. Error: %s [%d]", getpid(), strerror(errno), errno);
	}
	return ret;
}