Example #1
0
static void cpManagerReload(int sig)
{
    zval *group_conf = NULL;
    group_conf = cpGetConfig(CPGC.ini_file);
    if (!Z_BVAL_P(group_conf)) {
        cpLog("parse ini file[%s] error,%s reload error!", CPGC.ini_file, CPGC.title);
    } else {
        zval **v, **conf;
        if (zend_hash_find(Z_ARRVAL_P(group_conf), CPGC.title, strlen(CPGC.title) + 1, (void **) &conf) == SUCCESS) {
            if (pthread_mutex_lock(CPGS->mutex_lock) == 0) {
                if (zend_hash_find(Z_ARRVAL_PP(conf), ZEND_STRS("pool_max"), (void **) &v) == SUCCESS) {
                    convert_to_long(*v);
                    CPGS->worker_max = (int) Z_LVAL_PP(v);
                }
                if (zend_hash_find(Z_ARRVAL_PP(conf), ZEND_STRS("pool_min"), (void **) &v) == SUCCESS) {
                    convert_to_long(*v);

                    int new_min = (int) Z_LVAL_PP(v);
                    if (new_min > CPGC.worker_min) {//增加最小
                        while (CPGS->worker_num < new_min) {
                            cpCreate_worker_mem(CPGS->worker_num);
                            CPGS->workers_status[CPGS->worker_num] = CP_WORKER_IDLE;
                            CPGS->worker_num++; //先加 线程安全
                            int new_pid = cpFork_one_worker(CPGS->worker_num - 1);
                            if (new_pid < 0) {
                                cpLog("Fork worker process failed. Error: %s [%d]", strerror(errno), errno);
                            } else {
                                CPGS->workers[CPGS->worker_num - 1].pid = new_pid;
                            }
                        }
                    }
                    CPGC.worker_min = new_min;
                }
                if (zend_hash_find(Z_ARRVAL_PP(conf), ZEND_STRS("recycle_num"), (void **) &v) == SUCCESS) {
                    convert_to_long(*v);
                    CPGC.recycle_num = (int) Z_LVAL_PP(v);
                }
                if (zend_hash_find(Z_ARRVAL_PP(conf), ZEND_STRS("idel_time"), (void **) &v) == SUCCESS) {
                    convert_to_long(*v);
                    CPGC.idel_time = (int) Z_LVAL_PP(v);
                }
                if (pthread_mutex_unlock(CPGS->mutex_lock) != 0) {
                    cpLog("pthread_mutex_unlock. Error: %s [%d]", strerror(errno), errno);
                }
            }
        } else {
            cpLog("find %s failed,The reload can only modify 'pool_min','pool_max','recycle_num' and 'idel_time',if you want modify other options please restart pool", CPGC.title);
        }
        zval_ptr_dtor(&group_conf);
    }
}
Example #2
0
static void cpManagerReload(int sig)
{
    zval *group_conf = NULL, **v;
    group_conf = cpGetConfig(CPGC.ini_file);
    int gid = 0;
    zval **gid_ptr = NULL;
    cpGroup *G = NULL;
    if (!Z_BVAL_P(group_conf))
    {
        cpLog("parse ini file[%s]  reload error!", CPGC.ini_file);
    }
    else
    {
        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(group_conf)); zend_hash_has_more_elements(Z_ARRVAL_P(group_conf)) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(group_conf)))
        {
            zval **config;
            zend_hash_get_current_data(Z_ARRVAL_P(group_conf), (void**) &config);
            char *name;
            uint keylen;
            zend_hash_get_current_key_ex(Z_ARRVAL_P(group_conf), &name, &keylen, NULL, 0, NULL);
            if (strcmp(name, "common") != 0)
            {
                if (zend_hash_find(Z_ARRVAL_P(CPGS->group), name, strlen(name) + 1, (void **) &gid_ptr) == SUCCESS)
                {
                    gid = Z_LVAL_PP(gid_ptr);
                    G = &CPGS->G[gid];
                }
                else
                {
                    cpLog("can not add datasource when the server runing,if you want add it please restart");
                    return;
                }
                if (pthread_mutex_lock(G->mutex_lock) == 0)
                {
                    if (zend_hash_find(Z_ARRVAL_PP(config), ZEND_STRS("pool_max"), (void **) &v) == SUCCESS)
                    {
                        convert_to_long(*v);
                        G->worker_max = (int) Z_LVAL_PP(v);
                    }
                    if (zend_hash_find(Z_ARRVAL_PP(config), ZEND_STRS("pool_min"), (void **) &v) == SUCCESS)
                    {
                        convert_to_long(*v);
                        int new_min = (int) Z_LVAL_PP(v);
                        if (new_min > G->worker_min)
                        {//增加最小
                            while (G->worker_num < new_min)
                            {
                                cpCreate_worker_mem(G->worker_num, gid);
                                G->workers_status[G->worker_num] = CP_WORKER_IDLE;
                                G->worker_num++; //先加 线程安全
                                int new_pid = cpFork_one_worker(G->worker_num - 1, gid);
                                if (new_pid < 0)
                                {
                                    cpLog("Fork worker process failed. Error: %s [%d]", strerror(errno), errno);
                                }
                                else
                                {
                                    G->workers[G->worker_num - 1].pid = new_pid;
                                }
                            }
                        }
                        G->worker_min = new_min;
                    }

                    if (pthread_mutex_unlock(G->mutex_lock) != 0)
                    {
                        cpLog("pthread_mutex_unlock. Error: %s [%d]", strerror(errno), errno);
                    }
                }
            }
            else
            {
                if (zend_hash_find(Z_ARRVAL_PP(config), ZEND_STRS("recycle_num"), (void **) &v) == SUCCESS)
                {
                    convert_to_long(*v);
                    CPGC.recycle_num = (int) Z_LVAL_PP(v);
                }
                if (zend_hash_find(Z_ARRVAL_PP(config), ZEND_STRS("idel_time"), (void **) &v) == SUCCESS)
                {
                    convert_to_long(*v);
                    CPGC.idel_time = (int) Z_LVAL_PP(v);
                }
            }
        }

        zval_ptr_dtor(&group_conf);
    }
}
Example #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;
}
Example #4
0
static void cpTryGetWorkerId(cpConnection *conn, char * data, int fd, int len)
{
    if (pthread_mutex_lock(CPGS->mutex_lock) == 0)
    {
        int i;
        for (i = 0; i < CPGS->worker_num; i++)
        {
            if (CPGS->workers_status[i] == CP_WORKER_IDLE && i < CPGS->worker_max)
            {
                CPGS->workers_status[i] = CP_WORKER_BUSY;
                conn->worker_id = i;
                conn->release = CP_FD_NRELEASED;
                if (pthread_mutex_unlock(CPGS->mutex_lock) != 0)
                {
                    cpLog("pthread_mutex_unlock. Error: %s [%d]", strerror(errno), errno);
                }
                return;
            }
        }
        if (CPGS->worker_num < CPGS->worker_max)
        {//争抢失败增加一个worker
            conn->release = CP_FD_NRELEASED;
            conn->worker_id = CPGS->worker_num;
            cpCreate_worker_mem(CPGS->worker_num);
            CPGS->workers_status[CPGS->worker_num] = CP_WORKER_BUSY; //创建后立马分配,防止第一次too many connections
            CPGS->worker_num++; //先加 线程安全
            int ret = kill(CPGS->manager_pid, SIGRTMIN);
            if (ret < 0)
            {
                CPGS->worker_num--; //todo 
                cpLog("send sig error. Error: %s [%d]", strerror(errno), errno);
            }
        }
        else if (CPGC.use_wait_queue)
        {
            cpWaitList *node = (cpWaitList*) emalloc(sizeof (cpWaitList) + len);
            node->fd = fd;
            node->len = len;
            node->next = NULL;
            if (CPGS->WaitList)
            {
                CPGS->WaitTail->next = node;
                node->pre = CPGS->WaitTail;
                CPGS->WaitTail = node;
            }
            else
            {
                node->pre = NULL;
                CPGS->WaitList = CPGS->WaitTail = node;
            }
            memcpy(node->data, data, len);
            conn->release = CP_FD_WAITING;
        }
        if (pthread_mutex_unlock(CPGS->mutex_lock) != 0)
        {
            cpLog("pthread_mutex_unlock. Error: %s [%d]", strerror(errno), errno);
        }
    }
    else
    {
        cpLog("pthread_spin_lock. Error: %s [%d]", strerror(errno), errno);
    }
}
Example #5
0
int cpServer_start()
{
    int i, pid, ret, ping_pid, sock;
    if (CPGC.daemonize > 0)
    {
        if (daemon(0, 0) < 0)
        {
            return FAILURE;
        }
    }
    if ((sock = cpListen()) < 0)
    {
        cpLog("listen[1] fail");
        return FAILURE;
    }

    CPGS->master_pid = getpid();
    CPGL.process_type = CP_PROCESS_MASTER;
    cpList_create();

    pid = fork();
    switch (pid)
    {
            //创建manager进程
        case 0:
            for (i = 0; i < CPGC.worker_min; i++)
            {
                //alloc了max个 但是只启动min个
                ret = cpCreate_worker_mem(i);
                pid = cpFork_one_worker(i);
                if (pid < 0 || ret < 0)
                {
                    cpLog("Fork worker process fail");
                    return FAILURE;
                }
                else
                {
                    CPGS->workers[i].pid = pid;
                    CPGS->workers_status[i] = CP_WORKER_IDLE;
                }
            }


            //数据库坏连接检测恢复进程
            ret = cpCreate_ping_worker_mem();
            ping_pid = cpFork_ping_worker();
            if (ping_pid < 0 || ret < 0)
            {
                cpLog("Fork ping  process fail");
                return FAILURE;
            }
            CPGS->ping_workers->pid = ping_pid;


            //标识为管理进程
            CPGL.process_type = CP_PROCESS_MANAGER;
            CPGS->worker_num = CPGC.worker_min; //初始为min个worker
            ret = cpWorker_manager_loop();
            exit(ret);
            break;
            //主进程
        default:
            CPGS->manager_pid = pid;
            break;
        case -1:
        {
            cpLog("fork manager process fail");
            return FAILURE;
        }
    }

    cpSignalInit();
    if (cpReactor_start(sock) < 0)
    {
        cpLog("Reactor_start[1] fail");
        return FAILURE;
    }
    return SUCCESS;
}
Example #6
0
int cpServer_start()
{
    int w, pid, ret, sock, g;
    if (CPGC.daemonize > 0)
    {
        if (daemon(0, 0) < 0)
        {
            return FAILURE;
        }
    }
    if ((sock = cpListen()) < 0)
    {
        cpLog("listen[1] fail");
        return FAILURE;
    }

    CPGS->master_pid = getpid();
    CPGL.process_type = CP_PROCESS_MASTER;

    pid = fork();
    switch (pid)
    {
            //创建manager进程
        case 0:
            for (g = 0; g < CPGS->group_num; g++)
            {
                for (w = 0; w < CPGS->G[g].worker_min; w++)
                {
                    //alloc了max个 但是只启动min个
                    ret = cpCreate_worker_mem(w, g);
                    pid = cpFork_one_worker(w, g);
                    if (pid < 0 || ret < 0)
                    {
                        cpLog("Fork worker process fail");
                        return FAILURE;
                    }
                    else
                    {
                        CPGS->G[g].workers[w].pid = pid;
                        CPGS->G[g].workers_status[w] = CP_WORKER_IDLE;
                    }
                }
            }
            //数据库坏连接检测恢复进程
            //            ret = cpCreate_ping_worker_mem();
            //            ping_pid = cpFork_ping_worker();
            //            if (ping_pid < 0 || ret < 0)
            //            {
            //                cpLog("Fork ping  process fail");
            //                return FAILURE;
            //            }
            //            CPGS->ping_workers->pid = ping_pid;

            //标识为管理进程
            CPGL.process_type = CP_PROCESS_MANAGER;
            ret = cpWorker_manager_loop();
            exit(ret);
            break;
            //主进程
        default:
            CPGS->manager_pid = pid;
            break;
        case -1:
        {
            cpLog("fork manager process fail");
            return FAILURE;
        }
    }

    cpSignalInit();
    if (cpReactor_start(sock) < 0)
    {
        cpLog("Reactor_start[1] fail");
        return FAILURE;
    }
    return SUCCESS;
}