static void test_io_close(int with_timer, bool from_path) { #define chunks 4 #define READSIZE (512*1024) unsigned int i; const char *path = LARGE_FILE; int fd = open(path, O_RDONLY); if (fd == -1) { if (errno == ENOENT) { test_skip("Large file not found"); return; } test_errno("open", errno, 0); test_stop(); } #ifdef F_GLOBAL_NOCACHE if (fcntl(fd, F_GLOBAL_NOCACHE, 1) == -1) { test_errno("fcntl F_GLOBAL_NOCACHE", errno, 0); test_stop(); } #endif struct stat sb; if (fstat(fd, &sb)) { test_errno("fstat", errno, 0); test_stop(); } const size_t size = (size_t)sb.st_size / chunks; const int expected_error = with_timer? ECANCELED : 0; dispatch_source_t t = NULL; dispatch_group_t g = dispatch_group_create(); dispatch_group_enter(g); void (^cleanup_handler)(int error) = ^(int error) { test_errno("create error", error, 0); dispatch_group_leave(g); close(fd); }; dispatch_io_t io; if (!from_path) { io = dispatch_io_create(DISPATCH_IO_RANDOM, fd, dispatch_get_global_queue(0, 0), cleanup_handler); } else { #if DISPATCHTEST_IO_PATH io = dispatch_io_create_with_path(DISPATCH_IO_RANDOM, path, O_RDONLY, 0, dispatch_get_global_queue(0, 0), cleanup_handler); #endif } dispatch_io_set_high_water(io, READSIZE); if (with_timer == 1) { dispatch_io_set_low_water(io, READSIZE); dispatch_io_set_interval(io, 2 * NSEC_PER_SEC, DISPATCH_IO_STRICT_INTERVAL); } else if (with_timer == 2) { t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0,0)); dispatch_retain(io); dispatch_source_set_event_handler(t, ^{ dispatch_io_close(io, DISPATCH_IO_STOP); dispatch_source_cancel(t); });
inline DISPATCH_ALWAYS_INLINE ~dispatch_block_private_data_s() noexcept { _dispatch_block_private_data_debug("destroy%s, block: %p", dbpd_magic ? "" : " (stack)", dbpd_block); if (dbpd_magic != DISPATCH_BLOCK_PRIVATE_DATA_MAGIC) return; if (dbpd_group) { if (!dbpd_performed) dispatch_group_leave(dbpd_group); ((void (*)(dispatch_group_t))dispatch_release)(dbpd_group); } if (dbpd_block) Block_release(dbpd_block); if (dbpd_voucher) voucher_release(dbpd_voucher); }
void test_proc(pid_t bad_pid) { dispatch_source_t proc_s[PID_CNT], proc; int res; pid_t pid, monitor_pid; event_cnt = 0; // Creates a process and register multiple observers. Send a signal, // exit the process, etc., and verify all observers were notified. posix_spawnattr_t attr; res = posix_spawnattr_init(&attr); assert(res == 0); #if HAVE_DECL_POSIX_SPAWN_START_SUSPENDED res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED); assert(res == 0); #endif char* args[] = { "/bin/sleep", "2", NULL }; res = posix_spawnp(&pid, args[0], NULL, &attr, args, NULL); if (res < 0) { perror(args[0]); exit(127); } res = posix_spawnattr_destroy(&attr); assert(res == 0); dispatch_group_t group = dispatch_group_create(); assert(pid > 0); monitor_pid = bad_pid ? bad_pid : pid; // rdar://problem/8090801 int i; for (i = 0; i < PID_CNT; ++i) { dispatch_group_enter(group); proc = proc_s[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, monitor_pid, DISPATCH_PROC_EXIT, dispatch_get_global_queue(0, 0)); test_ptr_notnull("dispatch_source_proc_create", proc); dispatch_source_set_event_handler(proc, ^{ long flags = dispatch_source_get_data(proc); test_long("DISPATCH_PROC_EXIT", flags, DISPATCH_PROC_EXIT); event_cnt++; dispatch_source_cancel(proc); }); dispatch_source_set_cancel_handler(proc, ^{ dispatch_group_leave(group); });
void dispatch_apply_fwrite(uint32_t* data) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); for (int fi = 0; fi < kNumFiles; ++fi) dispatch_group_enter(group); // There's no dispatch_group_apply(). dispatch_apply(kNumFiles, queue, ^(size_t fi) { char buf[80]; sprintf(buf, "f%02d.out", (int)fi); FILE* f = fopen(buf, "wb"); fwrite(data + fi * kIntChunkSize, 1, kChunkSize, f); fclose(f); dispatch_group_leave(group); });
void test_short_timer(void) { // Add a large number of timers with suspended target queue in front of // the timer being measured <rdar://problem/7401353> g = dispatch_group_create(); q = dispatch_queue_create("q", NULL); int i; for (i = 0; i < N; i++) { t[i] = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, q); dispatch_source_set_timer(t[i], DISPATCH_TIME_NOW, interval, 0); dispatch_group_enter(g); dispatch_source_set_registration_handler(t[i], ^{ dispatch_suspend(t[i]); dispatch_group_leave(g); }); dispatch_resume(t[i]); }
static void cancel_source(void *_source) { dispatch_source_t source = (dispatch_source_t)_source; int descriptor = dispatch_source_get_handle(source); asl_redirect_t *aslr = &redirect_descriptors[descriptor]; /* Flush the buffer */ _read_redirect(descriptor, 1); close(descriptor); asl_client_release(aslr->asl); asl_msg_release(aslr->msg); free(aslr->buf); memset(aslr, 0, sizeof(*aslr)); dispatch_release(source); dispatch_group_leave(read_source_group); }
static void test_concat(void) { dispatch_group_enter(g); dispatch_async(dispatch_get_main_queue(), ^{ char* buffer1 = "This is buffer1 "; size_t size1 = 17; char* buffer2 = "This is buffer2 "; size_t size2 = 17; __block bool buffer2_destroyed = false; dispatch_data_t data1 = dispatch_data_create(buffer1, size1, NULL, NULL); dispatch_data_t data2 = dispatch_data_create(buffer2, size2, dispatch_get_main_queue(), ^{ buffer2_destroyed = true; }); dispatch_data_t concat = dispatch_data_create_concat(data1, data2); dispatch_release(data1); dispatch_release(data2); test_long("Data size of concatenated dispatch data", dispatch_data_get_size(concat), 34); const void* contig; size_t contig_size; dispatch_data_t contig_data = dispatch_data_create_map(concat, &contig, &contig_size); dispatch_release(concat); dispatch_release(contig_data); test_long("Contiguous memory size", contig_size, 34); dispatch_async(dispatch_get_main_queue(), ^{ test_long("buffer2 destroyed", buffer2_destroyed, true); dispatch_group_leave(g); });
int main(int argc, char** argv) { struct hostent *he; int sockfd, clientfd; struct sockaddr_in addr1, addr2, server; socklen_t addr2len; socklen_t addr1len; pid_t clientid; const char *path = "/usr/share/dict/words"; int read_fd, fd; if (argc == 2) { // Client dispatch_test_start(NULL); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { test_errno("Client-socket()", errno, 0); test_stop(); } if ((he = gethostbyname("localhost")) == NULL) { fprintf(stderr, "Client-gethostbyname() failed\n"); test_stop(); } memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length); server.sin_family = AF_INET; server.sin_port = atoi(argv[1]); fprintf(stderr, "Client-connecting on port ... %d\n", server.sin_port); if (connect(sockfd, (struct sockaddr *)&server, sizeof(server))) { test_errno("client-connect()", errno, 0); test_stop(); } // Read from the socket and compare the contents are what we expect fd = open(path, O_RDONLY); if (fd == -1) { test_errno("client-open", errno, 0); test_stop(); } #ifdef F_NOCACHE if (fcntl(fd, F_NOCACHE, 1)) { test_errno("client-fcntl F_NOCACHE", errno, 0); test_stop(); } #else // investigate what the impact of lack of file cache disabling has // for this test #endif struct stat sb; if (fstat(fd, &sb)) { test_errno("client-fstat", errno, 0); test_stop(); } size_t size = sb.st_size; __block dispatch_data_t g_d1 = dispatch_data_empty; __block dispatch_data_t g_d2 = dispatch_data_empty; __block int g_error = 0; dispatch_group_t g = dispatch_group_create(); dispatch_group_enter(g); dispatch_read(fd, size, dispatch_get_global_queue(0, 0), ^(dispatch_data_t d1, int error) { test_errno("Client-dict-read error", error, 0); test_long("Client-dict-dispatch data size", dispatch_data_get_size(d1), size); dispatch_retain(d1); g_d1 = d1; dispatch_group_leave(g); });