Esempio n. 1
0
void timer_handler(void* context)
{
	struct timeval now_tv;
	double now;
	double goal;
	double jitter;
	double drift;

	gettimeofday(&now_tv, NULL);
	now = now_tv.tv_sec + ((double)now_tv.tv_usec / (double)USEC_PER_SEC);

	if (first == 0) {
		first = now;
	}

	goal = first + interval_d * count;
	jitter = goal - now;
	drift = jitter - last_jitter;

	count += dispatch_source_get_data(timer);
	jittersum += jitter;
	driftsum += drift;

	printf("%4d: jitter %f, drift %f\n", count, jitter, drift);
		
	if (count >= target) {
		test_double_less_than("average jitter", fabs(jittersum) / (double)count, 0.0001);
		test_double_less_than("average drift", fabs(driftsum) / (double)count, 0.0001);
		test_stop();
	}
	last_jitter = jitter;
}
Esempio n. 2
0
int
main(void)
{
	const char *path = "/usr/share/dict/words";
	struct stat sb;

	dispatch_test_start("Dispatch Source Read");

	int infd = open(path, O_RDONLY);
	if (infd == -1) {
		perror(path);
		exit(EXIT_FAILURE);
	}
	if (fstat(infd, &sb) == -1) {
		perror(path);
		exit(EXIT_FAILURE);
	}
	bytes_total = sb.st_size;

	if (fcntl(infd, F_SETFL, O_NONBLOCK) != 0) {
		perror(path);
		exit(EXIT_FAILURE);
	}

	if (!dispatch_test_check_evfilt_read_for_fd(infd)) {
		test_skip("EVFILT_READ kevent not firing for test file");
		test_fin(NULL);
	}

	dispatch_queue_t main_q = dispatch_get_main_queue();
	test_ptr_notnull("dispatch_get_main_queue", main_q);

	dispatch_source_t reader = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, infd, 0, main_q);
	test_ptr_notnull("dispatch_source_create", reader);
	assert(reader);

	dispatch_source_set_event_handler(reader, ^{
		size_t estimated = dispatch_source_get_data(reader);
		fprintf(stderr, "bytes available: %zu\n", estimated);
		test_double_less_than_or_equal("estimated", estimated, bytes_total - bytes_read);
		const ssize_t bufsiz = 1024*500; // 500 KB buffer
		static char buffer[1024*500];	// 500 KB buffer
		ssize_t actual = read(infd, buffer, sizeof(buffer));
		bytes_read += actual;
		printf("bytes read: %zd\n", actual);
		if (actual < bufsiz) {
			actual = read(infd, buffer, sizeof(buffer));
			bytes_read += actual;
			// confirm EOF condition
			test_long("EOF", actual, 0);
			dispatch_source_cancel(reader);
		}
	});
Esempio n. 3
0
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);
		});
Esempio n. 4
0
static void onSocketAccept()
{
	if( ! listener ) return;

	SocketClientRef client = calloc(1, sizeof(SocketClient));
	assert(client);
	socklen_t len = sizeof(client->addr);
	client->fd = accept(listener->fd, (struct sockaddr *)&client->addr, &len);

	dispatch_queue_t queue = dispatch_queue_create("ru.n3b.SocketReadQueue", NULL);
	client->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t) client->fd, 0, queue);
	dispatch_source_set_event_handler(client->source, ^{
		onSocketDataReceived(client, dispatch_source_get_data(client->source)); });
Esempio n. 5
0
chime_object_t* file_on_read(chime_object_t* instance, chime_object_t* context, chime_object_t* function)
{
#ifdef PLATFORM_MAC_OS_X
    int               descriptor;
    dispatch_queue_t  queue;
    dispatch_source_t source;
    //chime_object_t*   data_object;
    
    queue       = execution_context_get_dispatch_queue(context);
    descriptor  = file_get_file_descriptor(instance, READWRITE_DESCRIPTOR);
    //data_object = 
    
    source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, descriptor, 0, queue);
    file_set_dispatch_source(instance, FILE_READ_DISPATCH_SOURCE, source);
    
    chime_object_retain(function);
    dispatch_source_set_event_handler(source, ^{
        int             fd;
        size_t          estimated_size;
        ssize_t         actual_size;
        char*           buffer;
        chime_object_t* tagged_data;
        
        fd             = dispatch_source_get_handle(source);
        estimated_size = dispatch_source_get_data(source) + 1;
        
        if (estimated_size <= 1)
        {
            // fprintf(stderr, "** read zero, cancelling read source\n");
            dispatch_source_cancel(source);
            return;
        }
        
        //fprintf(stderr, "** estimated: %ld\n", estimated);
        
        buffer = (char*)malloc(estimated_size);
        assert(buffer);
        
        actual_size = read(fd, buffer, estimated_size);
        tagged_data = chime_tag_encode_raw_block(buffer);
        
        chime_closure_invoke_2((chime_closure_t*)function, tagged_data, chime_integer_encode(actual_size));
    });
Esempio n. 6
0
int
main(void)
{
	dispatch_test_start("Dispatch VM Pressure test"); // rdar://problem/7000945
	if (!dispatch_test_check_evfilt_vm()) {
		test_skip("EVFILT_VM not supported");
		test_stop();
		return 0;
	}
	initial = time(NULL);
	uint64_t memsize = _dispatch_get_memory_size();
	max_page_count = MIN(memsize, MAXMEM) / ALLOC_SIZE;
	pages = calloc(max_page_count, sizeof(char*));

	vm_queue = dispatch_queue_create("VM Pressure", NULL);
	vm_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VM, 0,
			DISPATCH_VM_PRESSURE, vm_queue);
	dispatch_source_set_event_handler(vm_source, ^{
		if (!page_count) {
			// Too much memory pressure already to start the test
			test_skip("Memory pressure at start of test");
			cleanup();
		}
		if (__sync_add_and_fetch(&handler_call_count, 1) != NOTIFICATIONS) {
			log_msg("Ignoring vm pressure notification\n");
			interval = 1;
			return;
		}
		test_long("dispatch_source_get_data()",
				dispatch_source_get_data(vm_source), NOTE_VM_PRESSURE);
		int32_t i, pc = page_count + 1;
		for (i = 0; i < pc && pages[i]; ++i) {
				free(pages[i]);
				pages[i] = NULL;
		}
		log_msg("Freed %ldMB\n", pg2mb(i));
	});
Esempio n. 7
0
static VALUE
rb_source_get_data(VALUE self, SEL sel)
{
    return LONG2NUM(dispatch_source_get_data(RSource(self)->source));
}
extern "C" void cxx_dispatch_proc_lambda(void)
{
    dispatch_source_t proc_native;
	int res;
	pid_t pid;

    MU_BEGIN_TEST(cxx_dispatch_proc_lambda);
	
	// Creates a process and register multiple observers.  Send a signal,
	// exit the process, etc., and verify all observers were notified.
	
	//
	// Simple child process that sleeps 2 seconds.
	//
	
	posix_spawnattr_t attr;
	res = posix_spawnattr_init(&attr);
    MU_ASSERT_TRUE( res );
	res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED);
    MU_ASSERT_TRUE( res );

	char* args[] = {
        (char*)"/bin/sleep", (char*)"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);
    MU_ASSERT_TRUE( res );

    xdispatch::queue* completion = new xdispatch::queue("completion");
	
    MU_ASSERT_TRUE(pid > 0);

	//
	// Suspend the "completion" queue when each observer is created.
	// Each observer resumes the queue when the child process exits.
	// If the queue is resumed too few times (indicating that not all
	// observers received the exit event) then the test case will not exit
	// within the alloted time and result in failure.
	//
	
	int i;
	for (i = 0; i < PID_CNT; ++i) {
        completion->suspend();
        proc_native = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, DISPATCH_PROC_EXIT, dispatch_get_main_queue());
        xdispatch::source* proc = new xdispatch::source( new xdispatch::native_source(proc_native) );
        MU_DESC_ASSERT_NOT_NULL("DISPATCH_SOURCE_TYPE_PROC", proc);

        proc->handler([=]{
            long flags = dispatch_source_get_data( proc->native_source() );
            MU_DESC_ASSERT_EQUAL("DISPATCH_PROC_EXIT", flags, DISPATCH_PROC_EXIT);
			event_cnt++;
            completion->resume();
		});

        proc->resume();
	}


	//
	// The completion block will be pending on the completion queue until it
	// has been fully resumed, at which point the test will exit successfully.
	//

    completion->async([=]{
		int status;
		int res2 = waitpid(pid, &status, 0);
        MU_ASSERT_TRUE(res2 != -1);
        MU_DESC_ASSERT_EQUAL("Sub-process exited", WEXITSTATUS(status) | WTERMSIG(status), 0);
        MU_DESC_ASSERT_EQUAL("Event count", event_cnt, PID_CNT);
        MU_PASS("");
	});

	kill(pid, SIGCONT);

    xdispatch::exec();

    MU_FAIL("Should never reach this");
    MU_END_TEST;
}