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); }
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; }
/* * 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; }
/* * 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); }