예제 #1
0
파일: msd_so.c 프로젝트: hq-cml/mossad
int main(int argc, char *argv[]) 
{
    void * handle;

    if (argc < 2) 
    {
        fprintf(stderr, "Invalid arguments\n");
        exit(1);
    }

    if (msd_load_so(&handle, syms, argv[1]) < 0) 
    {
        fprintf(stderr, "load so file failed\n");
        exit(1);
    }

    if (dll.handle_init) 
    {
        dll.handle_init("handle_init", 0);
    }

    dll.handle_task("handle_task");

    if (dll.handle_fini) 
    {
        dll.handle_fini("handle_fnit", 1);
    }

    msd_unload_so(&handle);
    exit(0);
}
예제 #2
0
파일: work.cpp 프로젝트: Zhanyin/taomee
/**
 * @brief  重启已停止work进程
 * @param
 * @return
 */
int monitor_work_proc(int argc, char* argv[], pid_t *wpids, int pid_count, bool /* use_barrier */)
{
    int result;
    pid_t old_pid, new_pid;
    int sec = 10;

    while (!g_stop) {
        struct timeval tv = {sec, 0};
        int sleep_ok = select(0, NULL, NULL, NULL, &tv);
        for (int i = 0; i < pid_count && sleep_ok == 0; ++i) {
            if(wpids[i] != 0) {
                result = kill(wpids[i], 0);
                if (0 == result || errno != ESRCH) {
                    continue;
                }
            }
            if (!g_stop) {
                old_pid = wpids[i];

                /// WORK进程异常退出时,需要清理过滤器中这个进程的资源
                if (g_bench_conf.use_barrier) {
                    AFUTEX_LOCK_ERR_CHK(g_rcv_rq_lock);
                    g_prcv_brq->clean_4pid(old_pid);
                    AFUTEX_UNLOCK_ERR_CHK(g_rcv_rq_lock);
                }

                new_pid = fork();
                if(new_pid < 0) {
                    wpids[i] = 0;
                    ERROR_LOG("Work[%u] exited, and fork failed: %s", new_pid, strerror(errno));
                } else if(new_pid > 0) {///parent process
                    wpids[i] = new_pid;
                    ERROR_LOG("Work[%u] exited, fork[%u] to replace.", old_pid, new_pid);
                } else {
                    run_work_proc(argc, argv, g_bench_conf.use_barrier);
                }
            }
        }

        if (dll.handle_timer) {
            dll.handle_timer(&sec);
        }
    }

    if (dll.handle_fini) {
        dll.handle_fini(PROC_MAIN);
    }

    ///wait for all child processes end
    for (int i = 0; i < pid_count; ) {
        if (wpids[i] != 0) {
            result = kill(wpids[i], 0);
            if (result != 0 && errno == ESRCH) {
                /// 等待下一个进程
                ++i;
            } else {
                /// 继续等待 50 毫秒
                usleep(50000);
                continue;
            }
        }
    }

    return 0;
}
예제 #3
0
파일: work.cpp 프로젝트: Zhanyin/taomee
/**
 * @brief  启动work进程
 * @param
 * @return
 */
int run_work_proc(int argc, char *argv[], bool /* use_barrier */)
{
    setproctitle("%s:[WORK]", g_bench_conf.prog_name);
    
    if (dll.handle_init != NULL && dll.handle_init(argc, argv, PROC_WORK) != 0) {
        print_prompt(false, "Worker process handle_init failed.");
        return -1;
    }

    /// 由于环形队列中有头 shm_block_t,所以需要给头预留空间
    int prcv_data_len = g_bench_conf.max_pkg_len + sizeof(shm_block_t);
    char *prcv_data = (char *)malloc(prcv_data_len);

    if (prcv_data == NULL) {
        print_prompt(false, "Malloc work proc pop buffer fail, size: %d B", prcv_data_len);
        return -1;
    }

    shm_block_t *mb = (shm_block_t *)prcv_data;
    int sndlen = 0;
    int ret = 0;
    char *puser_data = NULL;

    if (g_bench_conf.use_barrier == true) {
        if (g_prcv_brq == NULL) {
            print_prompt(false, "Use barrier mode, but i_barrier_ring_queue is null.");
            goto work_proc_end;
        }

        while (! g_stop) {
            if (dll.handle_schedule) {
                dll.handle_schedule();
            }

            if (!g_prcv_brq->is_able_pop()) {
                /// 等待数据
                struct timespec tv = {0, 200000};
                nanosleep(&tv, NULL);
                continue;
            }

            AFUTEX_LOCK_ERR_CHK(g_rcv_rq_lock);
            ret = g_prcv_brq->pop(prcv_data, prcv_data_len);
            AFUTEX_UNLOCK_ERR_CHK(g_rcv_rq_lock);
            if (ret < 0) {
                ERROR_LOG("Barrier pop error: %d", g_prcv_brq->get_last_errno());
                sleep(1);  /// 防止出错以后打印日志速度太快
                continue;
            } else if (ret == 0) {
                /// 没有取出任何数据
                continue;
            } else {
                if(ret != mb->length || (u_int)mb->length <= sizeof(shm_block_t) || 
                   mb->length > prcv_data_len) {
                    /// 数据包包长有误,关闭这个连接
                    ERROR_LOG("Pop data len(%d) err, pkg len(%d), prcv_data_len(%d), shm_block_t(%zd), close conn: %d.",
                            ret, mb->length, prcv_data_len, sizeof(shm_block_t), mb->blk_id);
                    work_proc_close_conn(mb);
                    continue;
                }
            }

            TRACE_LOG("Pop barrier ring queue len: %d", mb->length);

            sndlen = 0;
            ret = dll.handle_process(mb->data, mb->length - sizeof(shm_block_t), &puser_data, &sndlen, &mb->skinfo);

            if (ret != 0) {
                work_proc_close_conn(mb);
                TRACE_LOG("Handle_process fail, close conn: %d", mb->blk_id);
            } else if(sndlen + sizeof(shm_block_t) > (u_int)prcv_data_len) {
                work_proc_close_conn(mb);
                ERROR_LOG("Handle_process sndlen(%d) > buf len, close conn: %d", sndlen, mb->blk_id);
            } else {
                if (sndlen > 0) {
                    mb->length = sndlen + sizeof(shm_block_t);
                    mb->type = DAT_BLOCK;
                    memcpy(mb->data, puser_data, sndlen);

                    AFUTEX_LOCK_ERR_CHK(g_snd_rq_lock);
                    ret = g_psnd_rq->push_data(prcv_data, mb->length, true);
                    AFUTEX_UNLOCK_ERR_CHK(g_snd_rq_lock);

                    if (ret != mb->length) {
                        ERROR_LOG("Push data(len: %d) error (ret: %d, data: %d, empty: %d)", mb->length,
                                  g_psnd_rq->get_last_errno(), g_psnd_rq->get_data_len(), g_psnd_rq->get_empty_buffer_len());
                    } else {
                        TRACE_LOG("ring queue push data len: %d", mb->length);
                        g_p_net_io_notifier->popup();
                    }
                }
            }
        }
    } else {
        if (g_prcv_rq == NULL) {
            print_prompt(false, "Use nonbarrier mode, but i_ring_queue object is null.");
            goto work_proc_end;
        }

        while (!g_stop) {
            if (dll.handle_schedule != NULL) {
                dll.handle_schedule();
            }

            if (g_prcv_rq->get_data_len() <= 0) {
                struct timespec tv = {0, 200000};
                nanosleep (&tv, NULL);
                continue;
            }

            AFUTEX_LOCK_ERR_CHK(g_rcv_rq_lock);
            ret = g_prcv_rq->pop_data(prcv_data, prcv_data_len, 0);
            AFUTEX_UNLOCK_ERR_CHK(g_rcv_rq_lock);
            if (ret < 0) {
                ERROR_LOG("Common ring queue pop fail(ret: %d): %s", ret, g_prcv_rq->get_last_errstr());
                sleep(1); /// 防止日志打印过快
                continue;
            } else if (ret == 0) {
                /// 数据还没准备好
                continue;
            } else {
                if(ret != mb->length || (u_int)mb->length <= sizeof(shm_block_t) || mb->length > prcv_data_len) {
                    /// 数据包包长有误,关闭这个连接
                    ERROR_LOG("Pop data len(%d) err, pkg len(%d), prcv_data_len(%d), shm_block_t(%zd), close conn: %d.",
                            ret, mb->length, prcv_data_len, sizeof(shm_block_t), mb->blk_id);
                    work_proc_close_conn(mb);
                    continue;
                }
            }
            TRACE_LOG("Common ring queue pop len: %d", mb->length);

            sndlen = 0;
            ret = dll.handle_process(mb->data, mb->length - sizeof(shm_block_t), &puser_data, &sndlen, &mb->skinfo);
            if (ret != 0) {
                work_proc_close_conn(mb);
                TRACE_LOG("Handle process fail, close conn: %d", mb->blk_id);
            } else if(sndlen + sizeof(shm_block_t) > (u_int)prcv_data_len) {
                work_proc_close_conn(mb);
                ERROR_LOG("Handle_process sndlen(%zd) > buf len %d, close conn: %d",
                        sndlen + sizeof(shm_block_t), prcv_data_len, mb->blk_id);
            } else {
                if (sndlen > 0) {
                    mb->length = sndlen + sizeof(shm_block_t);
                    mb->type = DAT_BLOCK;
                    memcpy(mb->data, puser_data, sndlen);

                    AFUTEX_LOCK_ERR_CHK(g_snd_rq_lock);
                    ret = g_psnd_rq->push_data(prcv_data, mb->length, true);
                    AFUTEX_UNLOCK_ERR_CHK(g_snd_rq_lock);

                    if (ret != mb->length) {
                        ERROR_LOG("Push data(len: %d) error (ret: %d, data: %d, empty: %d)", mb->length,
                                g_psnd_rq->get_last_errno(), g_psnd_rq->get_data_len(), g_psnd_rq->get_empty_buffer_len());
                    } else {
                        TRACE_LOG("Common ring queue push len: %d", mb->length);
                        g_p_net_io_notifier->popup();
                    }
                }
            }
        }
    }

work_proc_end:
    free(prcv_data);
    if (g_p_send_buff != NULL) {
        free(g_p_send_buff);
        g_p_send_buff = NULL;
        g_send_buff_len = 0;
    }
    if (dll.handle_fini != NULL) {
        dll.handle_fini(PROC_WORK);
    }
    return 0;
}
예제 #4
0
파일: connect.cpp 프로젝트: Zhanyin/taomee
/**
 * @brief  创建conn进程
 * @param
 * @return 0:success, -1:fail
 */
int conn_proc(int argc, char **argv)
{
    //建立TCP连接
    if (g_bench_conf.bind_list == NULL)
    {
        NB_BOOT_LOG(-1, "Bind info is null.");
        return -1;
    }

    //暂时仅支持一个端口
    struct bind_config *bc = g_bench_conf.bind_list;
    if (bc->type != SOCK_STREAM)
    {
        NB_BOOT_LOG(-1, "Warning: cannot support UDP now.");
        return -1;
    }

    c_newbench_net_io_event nb_event;
    if (nb_event.init() != 0)
    {
        NB_BOOT_LOG(-1, "Init c_newbench_net_io_event object failed.");
        return -1;
    }

    if (pnb_io_server->init(bc->bind_ip,
                            bc->bind_port,
                            &nb_event,
                            g_p_net_io_notifier,
                            1,
                            1) != 0)
    {
        NB_BOOT_LOG(-1, "Bind [%s:%u]: %s", bc->bind_ip,
                bc->bind_port, pnb_io_server->get_last_errstr());
        return -1;
    }

    NB_BOOT_LOG(0, "Listen on %s:%u", bc->bind_ip, bc->bind_port);

    int psnd_data_len = g_bench_conf.max_pkg_len + sizeof(shm_block_t);
    char *psnd_data = (char *)malloc(psnd_data_len);
    if (psnd_data == NULL)
    {
        NB_BOOT_LOG(-1, "Malloc package send buffer fail, size: %d B", g_bench_conf.max_pkg_len);
        return -1;
    }

    if (dll.handle_init && dll.handle_init(argc, argv, PROC_CONN) != 0)
    {
        NB_BOOT_LOG(-1, "Conn handle init fail.");
        return -1;
    }

    setproctitle("%s:[CONN]", g_bench_conf.prog_name);

    shm_block_t* mb = (shm_block_t*)psnd_data;

    while(!g_stop)
    {
        // 每次阻塞1毫秒, 因后面要发送数据
        // TODO:时间应该是可配的
        if (pnb_io_server->do_io(4,
                                 NET_IO_SERVER_CMD_ACCEPT
                                 | NET_IO_SERVER_CMD_READ
                                 | NET_IO_SERVER_CMD_WRITE) != 0)
        {
            ERROR_LOG("do_io fail: %s", pnb_io_server->get_last_errstr());
        }

        // 发送发送环形队列中的数据包, 发干净为止
        while (!g_stop)
        {
            // 取出数据包
            int ret = g_psnd_rq->pop_data(psnd_data, psnd_data_len, 0);

            if (ret == 0)
            {
                break;
            }
            else if (ret < 0)
            {
                // 发生错误
                ERROR_LOG("Pop data error, ret: %d, err: %s", ret, g_psnd_rq->get_last_errstr());
                break;
            }
            else
            {
                if (ret != mb->length || mb->length > psnd_data_len)
                {
                    // 出错, 打印日志以后退出发送
                    ERROR_LOG("pop data len %d != pkg len %d or > psnd_data_len", mb->length, psnd_data_len);
                    break;
                }
            }

            if (mb->type == FIN_BLOCK)
            {
                pnb_io_server->close_connection(mb->blk_id, true);
                continue;
            }

            TRACE_LOG("common ring queue pop data length: %d", mb->length);

            // 发送数据
            int bytes_sent = 0;
            int data_len = mb->length - sizeof(shm_block_t);

            if (data_len)
            {
                if (mb->type == BROADCAST_BLOCK)
                {
                    ret = pnb_io_server->broadcast(
                            mb->blk_id,
                            (char*)mb->data + bytes_sent,
                            data_len - bytes_sent,
                            1);

                    if (ret)
                    {
                        // 广播报文为全部成功
                        ERROR_LOG("broadcast not success at all, %d failed",
                                  ret);
                    }
                }
                else
                {
                    ret = pnb_io_server->send_data_atomic(
                            mb->blk_id,
                            (char*)mb->data + bytes_sent,
                            data_len - bytes_sent);

                    if (ret != data_len - bytes_sent)
                    {
                        // 发送数据失败时丢弃这个包
                        ERROR_LOG("Send to conn(%d) fail, len: %d, discard this pkg.", mb->blk_id, mb->length);
                    }
                    else
                    {
                        if (mb->skinfo.ptr_lookout)
                        {
                            // 传回storage
                            reinterpret_cast<union net_io_storage *>(mb->skinfo.ptr_lookout)->u64
                                = mb->skinfo.storage.u64;
                        }
                    }
                }
            }
        }
    }

    free(psnd_data);

    if (dll.handle_fini)
    {
        dll.handle_fini(PROC_CONN);
    }

    return 0;
}