CPINLINE int cli_real_send(cpClient *cli, zval *send_data,cpMasterInfo *info) {
    int ret = 0;
    if (cli->released == CP_FD_RELEASED) {
        cpTcpEvent event;
        event.type = CP_TCPEVENT_GET;
        event.ClientPid = cpPid;
        int ret = cpClient_send(cli->sock, (char *) &event, sizeof (event), 0);
        if (ret < 0) {
            zend_error(E_ERROR, "send failed in GET. Error:%d", errno);
        }
        int n = cpClient_recv(cli, info, sizeof (cpMasterInfo), 1);
        if (n > 0) {
            ret = CP_CLIENT_SERIALIZE_SEND_MEM(send_data, info->worker_id, info->max, info->semid);
            if (ret == SUCCESS) {
                cli->released = CP_FD_NRELEASED;
            }
        } else if (n == 0) {
            php_pdo_connect_pool_close(cli);
            zend_error(E_ERROR, "connect_pool: connect with conPool close");
        } else {
            zend_error(E_ERROR, "connect_pool: recv failed. Error: %s [%d]", strerror(errno), errno);
        }
    } else {
        ret = CP_CLIENT_SERIALIZE_SEND_MEM(send_data, info->worker_id, info->max, info->semid);
    }
    return ret;
}
示例#2
0
static void* connect_pool_perisent(zval* zres, zval* data_source)
{
    //        cpLog_init("/tmp/pool_client.log");
    zend_rsrc_list_entry sock_le;
    int ret;
    cpClient* cli = (cpClient*) pecalloc(sizeof (cpClient), 1, 1);
    if (cpClient_create(cli) < 0)
    {
        php_error_docref(NULL TSRMLS_CC, E_ERROR, "pdo_connect_pool: create sock fail. Error: %s [%d]", strerror(errno), errno);
    }
    ret = cpClient_connect(cli, "127.0.0.1", 6253, (float) 100, 0); //所有的操作100s超时
    if (ret < 0)
    {
        pefree(cli, 1);
        return NULL;
    }
    sock_le.type = le_cli_connect_pool;
    sock_le.ptr = cli;
    ZEND_REGISTER_RESOURCE(zres, cli, le_cli_connect_pool);
    zend_hash_update(&EG(persistent_list), Z_STRVAL_P(data_source), Z_STRLEN_P(data_source), (void*) &sock_le, sizeof (zend_rsrc_list_entry), NULL);
    cli->lock = cpMutexLock;
    cli->unLock = cpMutexUnLock;

    cpTcpEvent event = {0};
    event.type = CP_TCPEVENT_GETFD;
    cpClient_send(cli->sock, (char *) &event, sizeof (event), 0);
    cpMasterInfo info;
    ret = cpClient_recv(cli->sock, &info, sizeof (cpMasterInfo), 1);
    if (ret < 0)
    {
        php_error_docref(NULL TSRMLS_CC, E_ERROR, "recv from pool server error  [%d],%s", errno, strerror(errno));
    }
    cli->server_fd = info.server_fd;
    cpClient_attach_mem();
    CONN(cli)->release = CP_FD_RELEASED;
    return cli;
}
示例#3
0
CPINLINE cpGroup * cpGet_worker(cpClient *cli, zval **data_source)
{
    cpGroup *G = NULL;
    int group_id, worker_index;
    for (group_id = 0; group_id < CPGS->group_num; group_id++)
    {
        if (strcmp(Z_STRVAL_PP(data_source), CPGS->G[group_id].name) == 0)
        {
            G = &CPGS->G[group_id];
            cpConnection *conn = CONN(cli);
            if (cli->lock(G) == 0)
            {
                for (worker_index = 0; worker_index < G->worker_num; worker_index++)
                {
                    if (G->workers_status[worker_index] == CP_WORKER_IDLE && worker_index < G->worker_max)
                    {
                        G->workers_status[worker_index] = CP_WORKER_BUSY;
                        G->workers[worker_index].CPid = cpPid; //worker for this pid
                        conn->release = CP_FD_NRELEASED;
                        conn->worker_id = group_id * CP_GROUP_LEN + worker_index;
                        conn->group_id = group_id;
                        conn->worker_index = worker_index;
                        break;
                    }
                }
                if (conn->release == CP_FD_RELEASED)
                {
                    if (G->worker_num < G->worker_max)
                    {//add
                        conn->worker_index = G->worker_num;
                        conn->release = CP_FD_NRELEASED;
                        conn->worker_id = group_id * CP_GROUP_LEN + conn->worker_index;
                        conn->group_id = group_id;
                        G->workers_status[conn->worker_index] = CP_WORKER_BUSY;
                        G->workers[conn->worker_index].CPid = cpPid; //worker for this pid
                        cpCreate_worker_mem(conn->worker_index, group_id);

                        cpTcpEvent event = {0};
                        event.type = CP_TCPEVENT_ADD;
                        event.data = conn->worker_index;
                        //                         event.ClientPid = cpPid;
                        G->worker_num++; //add first, for thread safe
                        int ret = cpClient_send(cli->sock, (char *) &event, sizeof (event), 0);
                        if (ret < 0)
                        {
                            php_error_docref(NULL TSRMLS_CC, E_ERROR, "send to server errro %s [%d]", strerror(errno), errno);
                        }
                    }
                    else
                    {// in queue
                        conn->wait_fpm_pid = cpPid;
                        conn->next_wait_id = 0;
                        if (G->last_wait_id)
                        {
                            CPGS->conlist[G->last_wait_id].next_wait_id = cli->server_fd;
                            G->last_wait_id = cli->server_fd;

                        }
                        else
                        {
                            G->first_wait_id = G->last_wait_id = cli->server_fd;
                        }
                        conn->release = CP_FD_WAITING;
                        conn->group_id = group_id;
                    }
                }
                cli->unLock(G);
            }
            break;
        }
    }
    return G;
}