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; }
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; }
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; }