int main() { srand(time(NULL)); ring *buf = ring_create(1 << 14); pthread_t w, w1, r, r1; // first we do a test with a single writer, single reader // in this test, the reader will ensure the sequence appears // strictly in the same order it is written arg_t args = { .buf = buf, .write_len = 1 << 22, .multi = false, }; pthread_create(&w, NULL, write_sequence, &args); pthread_create(&r, NULL, read_sequence, &args); pthread_join(w, NULL); int res; void *res_p; pthread_join(r, &res_p); res = *(int*)res_p; free(res_p); printf("single reader, single writer test passed: %s\n", res ? "FALSE" : "TRUE"); // now do 2 writers, 2 readers // we relax the sequence restriction and now just look for the same sums args.multi = true; pthread_create(&w, NULL, write_sequence, &args); pthread_create(&w1, NULL, write_sequence, &args); pthread_create(&r, NULL, read_sequence, &args); pthread_create(&r1, NULL, read_sequence, &args); int write_sum = 0; pthread_join(w, &res_p); write_sum += *(int*)res_p; free(res_p); pthread_join(w1, &res_p); write_sum += *(int*)res_p; free(res_p); int read_sum = 0; pthread_join(r, &res_p); read_sum += *(int*)res_p; free(res_p); pthread_join(r1, &res_p); read_sum += *(int*)res_p; free(res_p); printf("2 reader, 2 writer test passed: %s\n", (read_sum != write_sum) ? "FALSE" : "TRUE"); ring_destroy(buf); return res; }
int main() { //set buffer size as 5, first push 3 elements, and then pop 2 elements, then push 6 elements, at last pop 12 elements const int buffer_size = 5; int push_size_1 = 3; int pop_size_1 = 2; int push_size_2 = 6; int pop_size_2 = 12; void* data[buffer_size]; void* pop_data; struct ring* ring_buffer = ring_create( buffer_size ); int i; for( i = 0; i < push_size_1 ; i++){ data[i] = malloc(sizeof(int)); int err = ring_push(ring_buffer, &data[i]); if ( err == 0 ){ printf("push data %d = %d \n", i, &data[i]); } else{ printf("push %d failed \n ", i); } } for( i = 0; i < pop_size_1 ; i++){ pop_data = ring_pop(ring_buffer); if(pop_data == NULL){ printf("pop %d failed \n" , i); } else{ printf("pop data %d = %d\n", i, pop_data); } } for( i = 0; i < push_size_2 ; i++){ data[i] = malloc(sizeof(int)); int err = ring_push(ring_buffer, &data[i]); if ( err == 0 ){ printf("push data %d = %d \n", i, &data[i]); } else{ printf("push %d failed \n ", i); } } for( i = 0; i < pop_size_2 ; i++){ pop_data = ring_pop(ring_buffer); if(pop_data == NULL){ printf("pop %d failed \n" , i); } else{ printf("pop data %d = %d\n", i, pop_data); } } return 0; }
/** delayer main service routine */ static void service(const char* bind_str, int bindport, const char* serv_str, size_t memsize, int delay_msec) { struct sockaddr_storage bind_addr, srv_addr; socklen_t bind_len, srv_len; struct ringbuf* ring = ring_create(memsize); struct timeval delay, reuse; sldns_buffer* pkt; int i, s, listen_s; #ifndef S_SPLINT_S delay.tv_sec = delay_msec / 1000; delay.tv_usec = (delay_msec % 1000)*1000; #endif reuse = delay; /* reuse is max(4*delay, 1 second) */ dl_tv_add(&reuse, &delay); dl_tv_add(&reuse, &delay); dl_tv_add(&reuse, &delay); if(reuse.tv_sec == 0) reuse.tv_sec = 1; if(!extstrtoaddr(serv_str, &srv_addr, &srv_len)) { printf("cannot parse forward address: %s\n", serv_str); exit(1); } pkt = sldns_buffer_new(65535); if(!pkt) fatal_exit("out of memory"); if( signal(SIGINT, delayer_sigh) == SIG_ERR || #ifdef SIGHUP signal(SIGHUP, delayer_sigh) == SIG_ERR || #endif #ifdef SIGQUIT signal(SIGQUIT, delayer_sigh) == SIG_ERR || #endif #ifdef SIGBREAK signal(SIGBREAK, delayer_sigh) == SIG_ERR || #endif #ifdef SIGALRM signal(SIGALRM, delayer_sigh) == SIG_ERR || #endif signal(SIGTERM, delayer_sigh) == SIG_ERR) fatal_exit("could not bind to signal"); /* bind UDP port */ if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET, SOCK_DGRAM, 0)) == -1) { #ifndef USE_WINSOCK fatal_exit("socket: %s", strerror(errno)); #else fatal_exit("socket: %s", wsa_strerror(WSAGetLastError())); #endif } i=0; if(bindport == 0) { bindport = 1024 + random()%64000; i = 100; } while(1) { if(!ipstrtoaddr(bind_str, bindport, &bind_addr, &bind_len)) { printf("cannot parse listen address: %s\n", bind_str); exit(1); } if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) { #ifndef USE_WINSOCK log_err("bind: %s", strerror(errno)); #else log_err("bind: %s", wsa_strerror(WSAGetLastError())); #endif if(i--==0) fatal_exit("cannot bind any port"); bindport = 1024 + random()%64000; } else break; } fd_set_nonblock(s); /* and TCP port */ if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET, SOCK_STREAM, 0)) == -1) { #ifndef USE_WINSOCK fatal_exit("tcp socket: %s", strerror(errno)); #else fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError())); #endif } #ifdef SO_REUSEADDR if(1) { int on = 1; if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, (socklen_t)sizeof(on)) < 0) #ifndef USE_WINSOCK fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s", strerror(errno)); #else fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s", wsa_strerror(WSAGetLastError())); #endif } #endif if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) { #ifndef USE_WINSOCK fatal_exit("tcp bind: %s", strerror(errno)); #else fatal_exit("tcp bind: %s", wsa_strerror(WSAGetLastError())); #endif } if(listen(listen_s, 5) == -1) { #ifndef USE_WINSOCK fatal_exit("tcp listen: %s", strerror(errno)); #else fatal_exit("tcp listen: %s", wsa_strerror(WSAGetLastError())); #endif } fd_set_nonblock(listen_s); printf("listening on port: %d\n", bindport); /* process loop */ do_quit = 0; service_loop(s, listen_s, ring, &delay, &reuse, &srv_addr, srv_len, pkt); /* cleanup */ verbose(1, "cleanup"); #ifndef USE_WINSOCK close(s); close(listen_s); #else closesocket(s); closesocket(listen_s); #endif sldns_buffer_free(pkt); ring_delete(ring); }