Example #1
0
int swServer_udp_send(swServer *serv, swSendData *resp)
{
	socklen_t len;
	struct sockaddr_in addr_in;
	int sock = resp->info.from_fd;

	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons((unsigned short) resp->info.from_id); //from_id is port
	addr_in.sin_addr.s_addr = resp->info.fd; //from_id is port
	len = sizeof(addr_in);

	return swSendto(sock, resp->data, resp->info.len, 0, (struct sockaddr*) &addr_in, len);
}
Example #2
0
int swFactory_finish(swFactory *factory, swSendData *resp)
{
    int ret;
    swServer *serv = SwooleG.serv;

    //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_udp_send(serv, resp);
        goto finish;
    }
    else
    {
        resp->length = resp->info.len;
        swReactorThread_send(resp);
    }

    finish:
    if (ret < 0)
    {
        swWarn("sendto to reactor failed. Error: %s [%d]", 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;
}
Example #4
0
/**
 * worker: send to client
 */
int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
	int ret, sendn, count;
	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_udp_send(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;

	swConnection *conn = swServer_connection_get(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;
	swWorker *worker = swServer_get_worker(serv, SwooleWG.id);

	/**
	 * Big response, use shared memory
	 */
	if (resp->length > 0)
	{
		int64_t wait_reactor;

		/**
		 * Storage is in use right now, wait notify.
		 */
		if (worker->store.lock == 1)
		{
			worker->notify->read(worker->notify, &wait_reactor, sizeof(wait_reactor));
		}
		swPackage_response response;

		response.length = resp->length;
		response.worker_id = SwooleWG.id;

		//swWarn("BigPackage, length=%d|worker_id=%d", response.length, response.worker_id);

		sdata._send.info.from_fd = SW_RESPONSE_BIG;
		sdata._send.info.len = sizeof(response);

		memcpy(sdata._send.data, &response, sizeof(response));

		/**
		 * Lock the worker storage
		 */
		worker->store.lock = 1;
		memcpy(worker->store.ptr, resp->data, resp->length);
	}
	else
	{
		//copy data
		memcpy(sdata._send.data, resp->data, resp->info.len);

		sdata._send.info.len = resp->info.len;
		sdata._send.info.from_fd = SW_RESPONSE_SMALL;
	}

#if SW_REACTOR_SCHEDULE == 2
	sdata._send.info.from_id = fd % serv->reactor_num;
#else
	sdata._send.info.from_id = conn->from_id;
#endif

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

    //swWarn("send: sendn=%d|type=%d|content=%s", sendn, resp->info.type, resp->data);
    swTrace("[Worker]input_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 = serv->write_queue.in(&serv->write_queue, (swQueue_data *) &sdata, sendn);
        }
        else
        {
            int master_pipe = swWorker_get_write_pipe(serv, fd);
            //swWarn("send to reactor. fd=%d|pipe=%d|reactor_id=%d|reactor_pipe_num=%d", fd, master_pipe, conn->from_id, serv->reactor_pipe_num);
            ret = write(master_pipe, &sdata._send, sendn);

#ifdef SW_WORKER_WAIT_PIPE
            if (ret < 0 && errno == EAGAIN)
            {
                /**
                 * Wait pipe can be written.
                 */
                if (swSocket_wait(master_pipe, SW_WORKER_WAIT_TIMEOUT, SW_EVENT_WRITE) == SW_OK)
                {
                    continue;
                }
                else
                {
                    goto finish;
                }
            }
#endif
        }
		//swTraceLog("wt_queue->in: fd=%d|from_id=%d|data=%s|ret=%d|errno=%d", 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("sendto to reactor failed. Error: %s [%d]", strerror(errno), errno);
	}
	return ret;
}
Example #5
0
/**
 * worker: send to client
 */
int swFactoryProcess_finish(swFactory *factory, swSendData *resp)
{
    int ret, sendn;
    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)
    {
        return swServer_udp_send(serv, resp);
    }

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

    swConnection *conn = swServer_connection_get(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;
    swWorker *worker = swServer_get_worker(serv, SwooleWG.id);

	/**
     * Big response, use shared memory
     */
    if (resp->length > 0)
    {
        swPackage_response response;

        worker->lock.lock(&worker->lock);

        response.length = resp->length;
        response.worker_id = SwooleWG.id;

        //swWarn("BigPackage, length=%d|worker_id=%d", response.length, response.worker_id);

        sdata._send.info.from_fd = SW_RESPONSE_BIG;
        sdata._send.info.len = sizeof(response);

        memcpy(sdata._send.data, &response, sizeof(response));
        memcpy(worker->send_shm, resp->data, resp->length);
    }
    else
    {
        //copy data
        memcpy(sdata._send.data, resp->data, resp->info.len);

        sdata._send.info.len = resp->info.len;
        sdata._send.info.from_fd = SW_RESPONSE_SMALL;
    }

#if SW_REACTOR_SCHEDULE == 2
    sdata._send.info.from_id = fd % serv->reactor_num;
#else
    sdata._send.info.from_id = conn->from_id;
#endif

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

    ret = swWorker_send2reactor(&sdata, sendn, fd);

    finish:
    if (ret < 0)
    {
        swWarn("sendto to reactor failed. Error: %s [%d]", strerror(errno), errno);
    }
    return ret;
}