コード例 #1
0
ファイル: cpServer.c プロジェクト: damaainan/php-cp
static int cpReactor_client_receive(int fd)
{
    int event_size = sizeof (cpTcpEvent), n, ret = -1;
    char data[event_size];
    //非ET模式会持续通知
    n = cpNetRead(fd, data, event_size);
    if (n > 0)
    {
        cpTcpEvent *event = (cpTcpEvent*) data;
        switch (event->type)
        {
            case CP_TCPEVENT_ADD:
                ret = kill(CPGS->manager_pid, SIGRTMIN);
                if (ret < 0)
                {//TODO 
                    cpLog("send sig error. Error: %s [%d]", strerror(errno), errno);
                }
                break;
            case CP_TCPEVENT_GETFD:
            {
                cpMasterInfo info;
                info.server_fd = fd;
                CPGS->conlist[fd].fpm_pid = event->data;
                ret = cpWrite(fd, &info, sizeof (info));
                break;
            }
            default:
                cpLog("wrong type");
                break;
        }
        return ret;

    }
    else if (n == 0)
    {
close_fd:
        return cpReactor_client_close(fd);
    }
    else
    {//需要检测errno来区分是EAGAIN还是ECONNRESET
        if (errno == EAGAIN)
        {
            return SUCCESS;
        }
        else if (errno == ECONNRESET)
        {
            goto close_fd;
        }
        else
        {
            cpLog("Read from socket[%d] fail. Error: %s [%d]", fd, strerror(errno), errno);
            return SUCCESS;
        }
    }
    return SUCCESS;
}
コード例 #2
0
ファイル: cpClientNet.c プロジェクト: jqhph/php-cp
int cpClient_recv(int sock, void *data, int len, int waitall)
{
    //    int flag = 0, ret;
    //    if (waitall == 1) {
    //        flag = MSG_WAITALL;
    //    }
    //
    //    ret = recv(cli->sock, data, len, flag);
    //
    //    if (ret < 0) {
    //        if (errno == EINTR) {
    //            ret = recv(cli->sock, data, len, flag);
    //        } else {
    //            return SUCCESS;
    //        }
    //    }
    return cpNetRead(sock, data, len);
}
コード例 #3
0
ファイル: cpServer.c プロジェクト: mrzeta/php-cp
static int cpReactor_client_receive(int fd)
{
    int n;
    int event_size = sizeof (cpTcpEvent);
    char data[event_size];
    //非ET模式会持续通知
    n = cpNetRead(fd, data, event_size);

    cpConnection *conn = &(CPGS->conlist[fd]);
    if (n > 0)
    {
        cpTcpEvent *event = (cpTcpEvent*) data;
//                cpLog("evetn %d con %d",event->type,conn->release);
        if (event->type == CP_TCPEVENT_GET && conn->release == CP_FD_NRELEASED)
        {//动作是获得连接但是状态是未释放,父进程连的然后在子进程和父进程中都用这个连接,会出现这种情况
            cpMasterInfo info = {0};
            int sizeinfo = sizeof (info);
            info.worker_id = -1; //define it
            return cpWrite(fd, &info, sizeinfo);
        }
        if (event->type == CP_TCPEVENT_RELEASE)
        {
            return cpReactor_client_release(fd);
        }
        if (conn->release == CP_FD_RELEASED)
        {//之前释放了,或者刚进来的连接,需要争抢(这个状态不需要加锁,每个con的fd只分配给一个线程)
            cpTryGetWorkerId(conn, data, fd, n);
            if (conn->release == CP_FD_WAITING)
            {
                return 1;
            }
            if (conn->release == CP_FD_RELEASED)
            {//争抢失败,fork失败
                char tmp[sizeof (CP_TOO_MANY_CON_ERR) + sizeof (CP_CLIENT_EOF_STR)] = {CP_TOO_MANY_CON_ERR};
                strcat(tmp, CP_CLIENT_EOF_STR);
                return cpWrite(fd, tmp, strlen(tmp));
            }
        }
        return MasterSend2Client(fd, conn->worker_id, event->ClientPid);
    }
    else if (n == 0)
    {
close_fd:
        return cpReactor_client_close(fd);
    }
    else
    {//需要检测errno来区分是EAGAIN还是ECONNRESET
        if (errno == EAGAIN)
        {
            return SUCCESS;
        }
        else if (errno == ECONNRESET)
        {
            goto close_fd;
        }
        else
        {
            cpLog("Read from socket[%d] fail. Error: %s [%d]", fd, strerror(errno), errno);
            return SUCCESS;
        }
    }
    return SUCCESS;
}