static void * sock_read(void *arg) { (void)arg; struct sockaddr_in server_addr; char buf[32]; ssize_t nread; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); assert(sockfd > 0); CU_ASSERT(connect(sockfd, (struct sockaddr *)&server_addr, sizeof server_addr) == 0); crt_set_nonblock(sockfd); CU_ASSERT((nread=crt_tcp_read(sockfd, buf, sizeof buf)) == 6); if (nread != 6) { printf("\nnread = %zd, errcode = %d, err = %s\n", nread, crt_get_err_code(), strerror(crt_get_err_code())); } CU_ASSERT(crt_get_err_code() == 0); CU_ASSERT(memcmp(buf, "abcabc", 6) == 0); int ret = crt_tcp_read(sockfd, buf, sizeof buf); CU_ASSERT(ret == 0); CU_ASSERT(crt_get_err_code() == 0); close(sockfd); crt_exit(NULL); }
static void * tcp_timeout_connect(void *arg) { (void)arg; int fd; fd = crt_tcp_timeout_connect(inet_addr("127.0.0.1"), htons(2000), 100); CU_ASSERT(fd > 0); char buf[1024]; CU_ASSERT(crt_tcp_read(fd, buf, 6) == 6); CU_ASSERT(strcmp(buf, "abcabc") == 0); crt_sock_close(fd); crt_exit(NULL); }
static int execute_one_slave(int slave_id, int arg_cnt, ...) { va_list ap; int fd; char *request_stream; size_t request_len; int nread; fd = crt_tcp_timeout_connect(slave_ip(slave_id), slave_port(slave_id), MASTER_CONNECT_SLAVE_TIMEOUT); if (fd < 0) { if (crt_errno == ECONNREFUSED) return RET_CONNECT_REFUSED; else if (crt_errno == EWOULDBLOCK) return RET_CONNECT_TIMEOUT; else return RET_CONNECT_FAILED; } va_start(ap, arg_cnt); for (int i=0; i<arg_cnt; i++) { request_stream = va_arg(ap, char *); request_len = va_arg(ap, size_t); crt_tcp_write_to(fd, request_stream, request_len, MASTER_SEND_SLAVE_TIMEOUT); } va_end(ap); for ( ; ; ) { nread = crt_tcp_read_to(fd, return 0; } static struct query_response_s * fetch_result(struct query_request_s *request_ptr) { switch (request_ptr->cmd_type) { case cmd_sync: case cmd_power: case cmd_set: case cmd_delete: break; case cmd_get: break; default: break; } return NULL; } static int sendback_result(int fd, struct query_response_s *response_ptr) { return 0; } static void sendback_error_mesg(int fd) { const char *error_mesg = MC_ERR_STR; crt_tcp_write_to(fd, (void*)error_mesg, strlen(error_mesg), g_master_settings.write_timeout); } static void * handle_request(void *arg) { int fd = (intptr_t)arg; ssize_t nread; struct query_request_s request; struct query_response_s *response_ptr; char *p; char remote_ip[IP_STR_LEN]; struct sockaddr_in remote_peer; socklen_t addrlen; char warn_log_mesg[1024] = {0}; int ret; pre_timer(); launch_timer(); crt_set_nonblock(fd); addrlen = sizeof remote_peer; getpeername(fd, (struct sockaddr *)&remote_peer, &addrlen); inet_ntop(AF_INET, &(remote_peer.sin_addr), remote_ip, sizeof remote_ip); memset(&request, 0, sizeof request); /* {{{ recv header */ for (int i=0; i<MAX_RESP_HEADER_SIZE; i++) { nread = crt_tcp_read_to(fd, &request.query_head_buf[i], 1, g_master_settings.read_timeout); if (nread == 1) { if ((p=try_parse_memcached_string_head(&request)) == NULL) continue; else break; } else { ret = snprintf(warn_log_mesg, sizeof warn_log_mesg, "read sock failed: %d - %s", crt_errno, strerror(crt_errno)); assert(ret < (int)sizeof warn_log_mesg); /* NOT <= */ assert(ret >= 0); goto done; } } /* }}} */ /* {{{ parse header & prepare for receiving data */ request.query_head_buf_size = strlen(request.query_head_buf); if ((parse_memcached_string_head(&request) == RET_SUCCESS) && (request.parse_status == ps_succ)) { switch (request.cmd_type) { case cmd_set: request.data_size += 2; /* alloc for tailing '\r\n' */ request.data = slab_alloc(request.data_size); assert(request.data != NULL); nread = crt_tcp_read(fd, request.data, request.data_size); if (nread != (ssize_t)request.data_size) { ret = snprintf(warn_log_mesg, sizeof warn_log_mesg, "read request body failed: nread = %zd, error = %d - %s", nread, crt_errno, strerror(crt_errno)); assert(ret < (int)sizeof warn_log_mesg); /* NOT <= */ assert(ret >= 0); goto done; } break; case cmd_get: case cmd_delete: /* nothing to do */ break; /* TODO */ case cmd_sync: case cmd_power: default: break; } } else { sendback_error_mesg(fd); ret = snprintf(warn_log_mesg, sizeof warn_log_mesg, "parse request failed, cmd type: %d", request.cmd_type); assert(ret < (int)sizeof warn_log_mesg); /* NOT <= */ assert(ret >= 0); } /* }}} */ response_ptr = fetch_result(&request); sendback_result(fd, response_ptr); done: if (request.data != NULL) slab_free(request.data); stop_timer(); if (warn_log_mesg[0] == '\0') { log_notice("%s <Elapsed %ld.%06lds> {from: %s, fd = %d}", cmd_type_name(request.cmd_type), __used.tv_sec, __used.tv_usec, remote_ip, fd); } else { log_warn("%s <Elapsed %ld.%06lds> {from: %s, fd = %d} %s", cmd_type_name(request.cmd_type), __used.tv_sec, __used.tv_usec, remote_ip, fd, warn_log_mesg); } close(fd); crt_exit(NULL); }