static void * disk_read(void *arg) { (void)arg; int fd = 0; char buf[32]; Lock(doing_queue); CU_ASSERT(list_size(coroutine_env.doing_queue) == 0); UnLock(doing_queue); fd = crt_disk_open("./test_acoro.c", O_RDONLY); CU_ASSERT(fd > 0); ssize_t nread = crt_disk_read(fd, buf, sizeof buf); CU_ASSERT(crt_get_err_code() == 0); CU_ASSERT(nread == sizeof buf); CU_ASSERT(memcmp(buf, "/* © Copyright 2012 jingmi. All", sizeof buf) == 0); int ret = crt_disk_close(fd); CU_ASSERT(ret == 0); CU_ASSERT((uintptr_t)&buf[0] > (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr); CU_ASSERT((uintptr_t)&buf[0] < (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr + (uintptr_t)COROUTINE_STACK_SIZE); CU_ASSERT((uintptr_t)&buf[31] > (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr); CU_ASSERT((uintptr_t)&buf[31] < (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr + (uintptr_t)COROUTINE_STACK_SIZE); crt_exit(NULL); }
static void * sock_write(void *arg) { (void)arg; struct sockaddr_in server_addr; ssize_t nwrite; 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((nwrite=crt_tcp_write(sockfd, "abc", 3)) == 3); if (nwrite != 3) printf("written: %zd\n", nwrite); CU_ASSERT((nwrite=crt_tcp_write(sockfd, "xyz", 3)) == 3); if (nwrite != 3) printf("written: %zd\n", nwrite); CU_ASSERT(crt_get_err_code() == 0); int ret = crt_tcp_write(sockfd, "123", 3); CU_ASSERT(ret == 3); CU_ASSERT(crt_get_err_code() == 0); close(sockfd); crt_exit(NULL); }
void * sock_timeout(void *arg) { /* read nothing in this test case */ (void)arg; struct sockaddr_in server_addr; char buf[32]; struct timeval start, end, used; 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); gettimeofday(&start, NULL); CU_ASSERT(crt_tcp_read_to(sockfd, buf, sizeof buf, 10) == -1); CU_ASSERT(crt_get_err_code() == EWOULDBLOCK); gettimeofday(&end, NULL); (&used)->tv_sec = (&end)->tv_sec - (&start)->tv_sec; (&used)->tv_usec = (&end)->tv_usec - (&start)->tv_usec; if ((&used)->tv_usec < 0){ (&used)->tv_sec --; (&used)->tv_usec += 1000000; } CU_ASSERT(used.tv_sec == 0); CU_ASSERT(used.tv_usec <= 1000 * 20); /* more time to make sure: 20 ms */ close(sockfd); crt_exit(NULL); }
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 * disk_write(void *arg) { (void)arg; int fd; fd = crt_disk_open("/tmp/test_acoro.dat", O_WRONLY | O_CREAT | O_APPEND | O_TRUNC, S_IREAD | S_IWRITE); CU_ASSERT(fd > 0); ssize_t nwrite = crt_disk_write(fd, "abc", 3); CU_ASSERT(nwrite == 3); CU_ASSERT(crt_get_err_code() == 0); CU_ASSERT(crt_disk_close(fd) == 0); fd = open("/tmp/test_acoro.dat", O_RDONLY); char buf[16]; ssize_t nread = read(fd, buf, sizeof buf); CU_ASSERT(nread == 3); CU_ASSERT(memcmp(buf, "abc", 3) == 0); close(fd); struct stat sb; stat("/tmp/test_acoro.dat", &sb); CU_ASSERT(sb.st_size == 3); crt_exit(NULL); }
void * sock_timeout2(void *arg) { /* * read a bit of data in this test case * * the original intention is to test the following scenario: * 1. crt_tcp_read_to() read a few data from connection * 2. but it's timeout relative to it's argument * * if data was read, the standard activity should be: * 1. crt_tcp_read_to() return how many bytes have been read * 2. errno == 0 * * if nothing was read, then: * 1. crt_tcp_read_to() return -1 * 2. errno == EAGAIN or EWOULDBLOCK * * however, it's difficult to test the expected scenario due to it's hard * to control: * 1. crt_tcp_read_to() MUST be timeout * 2. data MUST be read * * it seems that if we send data as much as we can, it will be timeout */ (void)arg; struct sockaddr_in server_addr; char buf[32]; struct timeval start, end, used; 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); gettimeofday(&start, NULL); /* set the timeout duration to the least length: 1ms */ CU_ASSERT(crt_tcp_read_to(sockfd, buf, sizeof buf, 1) == 4); CU_ASSERT(crt_get_err_code() == 0); CU_ASSERT(strcmp(buf, "abc") == 0); gettimeofday(&end, NULL); (&used)->tv_sec = (&end)->tv_sec - (&start)->tv_sec; (&used)->tv_usec = (&end)->tv_usec - (&start)->tv_usec; if ((&used)->tv_usec < 0){ (&used)->tv_sec --; (&used)->tv_usec += 1000000; } CU_ASSERT(used.tv_sec == 0); CU_ASSERT(used.tv_usec <= 1000 * 20); /* more time to make sure: 20 ms */ close(sockfd); crt_exit(NULL); }
static void * null_coroutine(void *arg) { /* XXX Why crash when using printf() with arguments? */ /*printf("hello, %s\n", "world");*/ CU_ASSERT((intptr_t)arg == 0xbeef); crt_exit(NULL); }
static void * tcp_blocked_connect(void *arg) { (void)arg; int fd; fd = crt_tcp_blocked_connect(inet_addr("127.0.0.1"), htons(2000)); CU_ASSERT(fd > 0); crt_sock_close(fd); crt_exit(NULL); }
static void * call_in_coroutine(void *arg) { (void)arg; int c = mul(1, 2); CU_ASSERT(c == 2); CU_ASSERT((uintptr_t)&c > (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr); CU_ASSERT((uintptr_t)&c < (uintptr_t)coroutine_env.curr_task_ptr[ g_thread_id ]->stack_ptr + (uintptr_t)COROUTINE_STACK_SIZE); c = mul(100, 200); CU_ASSERT(c == 20000); 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); }
void * msleep_func(void *arg) { (void)arg; struct timeval start, end, used; int msleep_retval; gettimeofday(&start, NULL); msleep_retval = crt_msleep(10); gettimeofday(&end, NULL); (&used)->tv_sec = (&end)->tv_sec - (&start)->tv_sec; (&used)->tv_usec = (&end)->tv_usec - (&start)->tv_usec; if ((&used)->tv_usec < 0) { (&used)->tv_sec --; (&used)->tv_usec += 1000000; } CU_ASSERT(msleep_retval == 0); CU_ASSERT(used.tv_sec == 0); CU_ASSERT(used.tv_usec <= 1000 * 12); CU_ASSERT(used.tv_usec >= 1000 * 9); gettimeofday(&start, NULL); msleep_retval = crt_msleep(100); gettimeofday(&end, NULL); (&used)->tv_sec = (&end)->tv_sec - (&start)->tv_sec; (&used)->tv_usec = (&end)->tv_usec - (&start)->tv_usec; if ((&used)->tv_usec < 0) { (&used)->tv_sec --; (&used)->tv_usec += 1000000; } CU_ASSERT(msleep_retval == 0); CU_ASSERT(used.tv_sec == 0); CU_ASSERT(used.tv_usec <= 1000 * 102); CU_ASSERT(used.tv_usec >= 1000 * 99); CU_ASSERT(crt_msleep(0) == -1); crt_exit(NULL); }
void * bg_run_main_func(void *arg) { int write_fd = *(int*)arg; pthread_t tid, tid2; pthread_t self_tid = pthread_self(); struct timeval start, end, used; int ret = crt_bg_run(fetch_bg_thread_id, NULL, &tid); CU_ASSERT(ret == 100); CU_ASSERT(memcmp(&tid, &self_tid, sizeof tid) != 0); char buf[16] = {0}; memcpy(&buf[0], &tid, 8); memcpy(&buf[8], &self_tid, 8); gettimeofday(&start, NULL); ret = crt_bg_run(do_large_job_in_bg_worker, NULL, &tid2); gettimeofday(&end, NULL); (&used)->tv_sec = (&end)->tv_sec - (&start)->tv_sec; (&used)->tv_usec = (&end)->tv_usec - (&start)->tv_usec; if ((&used)->tv_usec < 0) { (&used)->tv_sec --; (&used)->tv_usec += 1000000; } CU_ASSERT(ret == 0x123); CU_ASSERT(memcmp(&tid, &tid2, sizeof tid)); CU_ASSERT(memcmp(&self_tid, &tid2, sizeof tid)); CU_ASSERT(used.tv_sec == 0); CU_ASSERT(used.tv_usec <= 1000 * 22); CU_ASSERT(used.tv_usec >= 1000 * 19); crt_disk_write(write_fd, buf, sizeof buf); crt_exit(NULL); }
void * disk_io_failed(void *arg) { (void)arg; int fd = crt_disk_open("/UnableOpened.dat", O_CREAT, S_IREAD | S_IWRITE); CU_ASSERT(fd == -1); int err_code = crt_get_err_code(); CU_ASSERT(err_code == EACCES); fd = crt_disk_open("/tmp/test_acoro.dat", O_RDONLY | O_CREAT | O_APPEND | O_TRUNC, S_IREAD); CU_ASSERT(fd > 0); char buf[16] = "abcdefg"; ssize_t nwrite = crt_disk_write(fd, buf, sizeof buf); CU_ASSERT(errno == 0); /* means we can NOT use system errno in coroutine */ CU_ASSERT(nwrite < 0); err_code = crt_get_err_code(); CU_ASSERT(err_code == EBADF); CU_ASSERT(crt_disk_close(fd) == 0); 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); }