Example #1
0
void *rs_start_accept_thread(void *data) 
{
    int                     err, cli_fd;
    socklen_t               socklen;
    rs_master_info_t        *mi;
    struct                  sockaddr_in cli_addr;
    rs_reqdump_data_t       *rd;

    mi = (rs_master_info_t *) data;

    pthread_cleanup_push(rs_free_accept_thread, mi);

    for( ;; ) {

        socklen = 0;
        rs_memzero(&cli_addr, sizeof(cli_addr));

        cli_fd = accept(mi->svr_fd, (struct sockaddr *) &cli_addr, &socklen);

        if(cli_fd == -1) {
            if(rs_errno == EINTR) {
                continue;
            }

            rs_log_error(RS_LOG_ERR, rs_errno, "accept() failed");
            goto free;
        }

        /* register slave */
        rd = rs_get_reqdump_data(mi->req_dump);

        if(rd == NULL) {
            goto free;
        }

        rd->pool = rs_create_pool(mi->pool_initsize, mi->pool_memsize, 
                1 * 1024 * 1024, RS_POOL_CLASS_IDX, mi->pool_factor, 
                RS_POOL_PREALLOC);

        if(rd->pool == NULL) {
            goto free;
        }

        /* init ring buffer */
        if((rd->ringbuf = rs_create_ringbuf(rd->pool, mi->ringbuf_num)) 
                == NULL)
        {
            goto free;
        }

        /* init packbuf */
        if((rd->send_buf = rs_create_tmpbuf(mi->sendbuf_size)) == NULL) {
            goto free; 
        }

        /* init iobuf */
        if((rd->io_buf = rs_create_tmpbuf(mi->iobuf_size)) == NULL) {
            goto free;
        }

        rd->cli_fd = cli_fd;
        rd->binlog_idx_file = mi->binlog_idx_file;
        rd->req_dump = mi->req_dump;
        rd->server_id = mi->server_id;

        /* create dump thread */
        if((err = pthread_create(&(rd->dump_thread), 
                        &(rd->req_dump->thr_attr), 
                        rs_start_dump_thread, (void *) rd)) != 0) 
        {
            rs_log_error(RS_LOG_ERR, err, "pthread_create() failed");
            goto free;
        }
    }

free:;

    pthread_cleanup_pop(1);
    pthread_exit(NULL);
}
Example #2
0
void *rs_start_accept_thread(void *data) 
{
    int                     err, cli_fd;
    socklen_t               socklen;
    rs_master_info_t        *mi;
    struct                  sockaddr_in cli_addr;
    rs_request_dump_t       *rd;

    mi = (rs_master_info_t *) data;

    pthread_cleanup_push(rs_free_accept_thread, mi);

    if(mi == NULL) {
        rs_log_err(0, "accept thread can not get master info struct");
        goto free;
    }

    rs_memzero(&cli_addr, sizeof(cli_addr));

    for( ;; ) {

        cli_fd = accept(mi->svr_fd, (struct sockaddr *) &cli_addr, &socklen);

        if(cli_fd == -1) {
            if(rs_errno == EINTR) {
                continue;
            }

            rs_log_err(rs_errno, "accept() failed");

            goto free;
        }

        /* register slave */
        rd = rs_get_request_dump(mi->req_dump_info);

        if(rd == NULL) {
            rs_log_err(0, "no more free request_dump struct");
            rs_close(cli_fd);
            cli_fd = -1;
            continue;
        } 

        rd->cli_fd = cli_fd;

        /* init ring buffer */
        if(rs_init_ring_buffer2(&(rd->ring_buf), RS_RING_BUFFER_NUM) != RS_OK) 
        {
            goto free;
        }

        /* init slab */
        if(rs_init_slab(&(rd->slab), NULL, mi->slab_init_size, mi->slab_factor
                    , mi->slab_mem_size, RS_SLAB_PREALLOC) != RS_OK) 
        {
            goto free;
        }

        /* create dump thread */
        if((err = pthread_create(&(rd->dump_thread), 
                        &(mi->req_dump_info->thread_attr), 
                        rs_start_dump_thread, (void *) rd)) != 0) 
        {
            rs_log_err(err, "pthread_create() failed, req_dump thread");
            goto free;
        }
    }

free:

    pthread_cleanup_pop(1);

    return NULL;
}
Example #3
0
/*
 *  Description
 *      Create listen fd for registering slaves.
 *      
 *  
 *  Return Value
 *      On success, RS_OK is returned. On error, RS_ERR is returned
 *
 */
int rs_dump_listen(rs_master_info_t *mi) 
{
    int     err, tries, reuseaddr;
    struct  sockaddr_in svr_addr;

    /* init var */
    reuseaddr = 1;
    rs_memzero(&svr_addr, sizeof(svr_addr));

    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(mi->listen_port);

    if (inet_pton(AF_INET, mi->listen_addr, &(svr_addr.sin_addr)) != 1) {
        rs_log_error(RS_LOG_ERR, rs_errno, "inet_pton() failed, %s", 
                mi->listen_addr);
        goto free;
    }

    for(tries = RS_RETRY_BIND_TIMES; tries; tries--) {
        mi->svr_fd = socket(AF_INET, SOCK_STREAM, 0);

        if(mi->svr_fd == -1) {
            rs_log_error(RS_LOG_ERR, rs_errno, "socket() failed");
            goto free;
        }

        if(setsockopt(mi->svr_fd, SOL_SOCKET, SO_REUSEADDR, 
                    (const void *) &reuseaddr, sizeof(int)) == -1)
        {
            rs_log_error(RS_LOG_ERR, rs_errno, "setsockopt(REUSEADDR) failed");
            goto free;
        }

        if(bind(mi->svr_fd, (const struct sockaddr *) &svr_addr, 
                    sizeof(svr_addr)) == -1) 
        {
            err = errno;
            mi->svr_fd = -1;

            if(err != EADDRINUSE) {
                rs_log_error(RS_LOG_ERR, err, "bind() failed");
                goto free;
            }

            rs_log_error(RS_LOG_INFO, 0, "try again to bind() after %ums"
                    , RS_RETRY_BIND_SLEEP_MSC);

            usleep(RS_RETRY_BIND_SLEEP_MSC * 1000);
            continue;
        }

        if(listen(mi->svr_fd, RS_BACKLOG) == -1) {
            rs_log_error(RS_LOG_ERR, rs_errno, "listen() failed");
            goto free;
        }

        break;
    }

    if(!tries) {
        goto free;
    }

    return RS_OK;

free : 
    return RS_ERR;
}
Example #4
0
/*
 *   rs_register_slave
 *   @s struct rs_slave_info_t
 *
 *   Connect to master, register a slave
 *
 *   No return value
 */
void *rs_start_io_thread(void *data)
{
    int                     r;
    int32_t                 pack_len;
    struct                  sockaddr_in svr_addr;
    rs_slave_info_t         *si;
    rs_ringbuf_data_t       *rbd;

    rs_memzero(&svr_addr, sizeof(svr_addr));
    si = (rs_slave_info_t *) data;

    /* push cleanup handle */
    pthread_cleanup_push(rs_free_io_thread, si);

    /* connect to master */
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(si->listen_port);

    if (inet_pton(AF_INET, si->listen_addr, &(svr_addr.sin_addr)) != 1) {
        rs_log_error(RS_LOG_ERR, rs_errno, "inet_pton(\"%s\") failed",
                     si->listen_addr);
        goto free;
    }

    for( ;; ) {

        si->svr_fd = socket(AF_INET, SOCK_STREAM, 0);

        if(si->svr_fd == -1) {
            rs_log_error(RS_LOG_ERR, rs_errno, "socket() failed");
            goto free;
        }

        if(connect(si->svr_fd, (const struct sockaddr *) &svr_addr,
                   sizeof(svr_addr)) == -1)
        {
            goto retry;
        }

        if(rs_send_dumpcmd(si) != RS_OK) {
            goto retry;
        }

        /* add to ring buffer */
        for( ;; ) {

            r = rs_ringbuf_set(si->ringbuf, &rbd);

            if(r == RS_FULL) {
                sleep(RS_RING_BUFFER_FULL_SLEEP_SEC);
                continue;
            }

            /* free slab chunk */
            if(rbd->data != NULL) {
                rs_pfree(si->pool, rbd->data, rbd->id);
            }


            if(rs_recv_tmpbuf(si->recv_buf, si->svr_fd, &pack_len, 4) != RS_OK)
            {
                goto retry;
            }

            /* alloc memory */
            rbd->len = pack_len;
            rbd->id = rs_palloc_id(si->pool, pack_len);
            rbd->data = rs_palloc(si->pool, pack_len, rbd->id);

            if(rbd->data == NULL) {
                goto free;
            }

            if(rs_recv_tmpbuf(si->recv_buf, si->svr_fd, rbd->data, rbd->len)
                    != RS_OK)
            {
                goto retry;
            }

            rs_ringbuf_set_advance(si->ringbuf);
        }

retry:
        /* close svr_fd retry connect */
        if(close(si->svr_fd) != 0) {
            rs_log_error(RS_LOG_ERR, 0, "close failed()");
        }
        si->svr_fd = -1;
        rs_log_error(RS_LOG_ERR, 0, "retry connect to master");
        sleep(RS_RETRY_CONNECT_SLEEP_SEC);
    }

free:
    ;

    pthread_cleanup_pop(1);
    pthread_exit(NULL);
}