/*
 * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#include <dispatch/dispatch.h>
#include <dispatch/private.h>
#ifdef __APPLE__
#include <mach/mach.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>

#include <bsdtests.h>
#include "dispatch_test.h"

#if TEST_MACHPORT_DEBUG
#define test_mach_assume_zero(x) ({kern_return_t _kr = (x); \
		if (_kr) fprintf(stderr, "mach error 0x%x \"%s\": %s\n", \
		_kr, mach_error_string(_kr), #x); (void)kr; })
void
test_mach_debug_port(mach_port_t name, const char *str, unsigned int line)
{
	mach_port_type_t type;
	mach_msg_bits_t ns = 0, nr = 0, nso = 0, nd = 0;
	unsigned int dnreqs = 0, dnrsiz;
	kern_return_t kr = mach_port_type(mach_task_self(), name, &type);
	if (kr) {
		fprintf(stderr, "machport[0x%08x] = { error(0x%x) \"%s\" }: %s %u\n",
				name, kr, mach_error_string(kr), str, line);
		return;
	}
	if (type & MACH_PORT_TYPE_SEND) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_SEND, &ns));
	}
	if (type & MACH_PORT_TYPE_SEND_ONCE) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_SEND_ONCE, &nso));
	}
	if (type & MACH_PORT_TYPE_DEAD_NAME) {
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_DEAD_NAME, &nd));
	}
	if (type & (MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND)) {
		test_mach_assume_zero(mach_port_dnrequest_info(mach_task_self(), name,
				&dnrsiz, &dnreqs));
		}
	if (type & MACH_PORT_TYPE_RECEIVE) {
		mach_port_status_t status = { .mps_pset = 0, };
		mach_msg_type_number_t cnt = MACH_PORT_RECEIVE_STATUS_COUNT;
		test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name,
				MACH_PORT_RIGHT_RECEIVE, &nr));
		test_mach_assume_zero(mach_port_get_attributes(mach_task_self(), name,
				MACH_PORT_RECEIVE_STATUS, (void*)&status, &cnt));
		fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) "
				"dnreqs(%03u) spreq(%s) nsreq(%s) pdreq(%s) srights(%s) "
				"sorights(%03u) qlim(%03u) msgcount(%03u) mkscount(%03u) "
				"seqno(%03u) }: %s %u\n", name, nr, ns, nso, nd, dnreqs,
				type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N",
				status.mps_nsrequest ? "Y":"N", status.mps_pdrequest ? "Y":"N",
				status.mps_srights ? "Y":"N", status.mps_sorights,
				status.mps_qlimit, status.mps_msgcount, status.mps_mscount,
				status.mps_seqno, str, line);
	} else if (type & (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|
			MACH_PORT_TYPE_DEAD_NAME)) {
		fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) "
				"dnreqs(%03u) spreq(%s) }: %s %u\n", name, nr, ns, nso, nd,
				dnreqs, type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N", str, line);
	} else {
		fprintf(stderr, "machport[0x%08x] = { type(0x%08x) }: %s %u\n", name,
				type, str, line);
	}
	fflush(stderr);
}
#define test_mach_debug_port(x) test_mach_debug_port(x, __func__, __LINE__)
#else
#define test_mach_debug_port(x) (void)(x)
#endif

static dispatch_group_t g;
static volatile long sent, received;

void
test_dead_name(void)
{
	dispatch_group_enter(g);
	dispatch_async(dispatch_get_global_queue(0, 0), ^{
		dispatch_source_t ds0;
		kern_return_t kr;

		mach_port_t mp = pthread_mach_thread_np(pthread_self());
		assert(mp);
		kr = mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_SEND, 1);
		test_mach_error("mach_port_mod_refs", kr, KERN_SUCCESS);
		ds0 = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, mp,
				DISPATCH_MACH_SEND_DEAD, dispatch_get_main_queue());
		test_ptr_notnull("DISPATCH_SOURCE_TYPE_MACH_SEND", ds0);
		dispatch_source_set_event_handler(ds0, ^{
			test_long("DISPATCH_MACH_SEND_DEAD",
					dispatch_source_get_handle(ds0), mp);
			dispatch_source_cancel(ds0);
		});
		dispatch_source_set_cancel_handler(ds0, ^{
			kern_return_t kr = mach_port_deallocate(mach_task_self(), mp);
			test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS);
			dispatch_release(ds0);
			dispatch_group_leave(g);
		});
		dispatch_resume(ds0);

		// give the mgr queue time to start, otherwise the mgr queue will run
		// on this thread, thus defeating the test which assumes that this
		// thread will die.
		usleep(100000);
	});
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
}

void
test_register_already_dead_name(void)
{
	dispatch_source_t ds0;
	kern_return_t kr;
	mach_port_t mp;

	dispatch_group_enter(g);
	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
	test_mach_error("mach_port_allocate", kr, KERN_SUCCESS);
	kr = mach_port_insert_right(mach_task_self(), mp, mp,
			MACH_MSG_TYPE_MAKE_SEND);
	test_mach_error("mach_port_insert_right", kr, KERN_SUCCESS);

	kr = mach_port_mod_refs(mach_task_self(), mp,
			MACH_PORT_RIGHT_RECEIVE, -1); // turn send right into dead name
	test_mach_error("mach_port_mod_refs", kr, KERN_SUCCESS);

	ds0 = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, mp,
			DISPATCH_MACH_SEND_DEAD, dispatch_get_global_queue(0, 0));
	dispatch_source_set_event_handler(ds0, ^{
		test_long("DISPATCH_MACH_SEND_DEAD",
				dispatch_source_get_handle(ds0), mp);
		dispatch_source_cancel(ds0);
		dispatch_release(ds0);
	});
	dispatch_source_set_cancel_handler(ds0, ^{
		kern_return_t kr = mach_port_deallocate(mach_task_self(), mp);
		test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS);
		dispatch_group_leave(g);
	});
	dispatch_resume(ds0);
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
}

void
test_receive_and_dead_name(void)
{
	dispatch_source_t ds0, ds;
	kern_return_t kr;
	mach_port_t mp;

	received = 0;
	dispatch_group_enter(g);
	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
	test_mach_error("mach_port_allocate", kr, KERN_SUCCESS);
	kr = mach_port_insert_right(mach_task_self(), mp, mp,
			MACH_MSG_TYPE_MAKE_SEND);
	test_mach_error("mach_port_insert_right", kr, KERN_SUCCESS);
	ds0 = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, mp,
			DISPATCH_MACH_SEND_DEAD, dispatch_get_global_queue(0, 0));
	dispatch_source_set_event_handler(ds0, ^{
		test_long("DISPATCH_MACH_SEND_DEAD",
				dispatch_source_get_handle(ds0), mp);
		dispatch_source_cancel(ds0);
		dispatch_release(ds0);
	});
	dispatch_source_set_cancel_handler(ds0, ^{
		kern_return_t kr = mach_port_deallocate(mach_task_self(), mp);
		test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS);
		dispatch_group_leave(g);
	});
	dispatch_resume(ds0);
	ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0,
			dispatch_get_global_queue(0, 0));
	dispatch_source_set_event_handler(ds, ^{
		__sync_add_and_fetch(&received, 1);
		usleep(100000); // rdar://problem/7676437 race with send source re-arm
		mach_msg_empty_rcv_t msg = { .header = {
			.msgh_size = sizeof(mach_msg_empty_rcv_t),
			.msgh_local_port = mp,
		}};
		kern_return_t kr = mach_msg_receive(&msg.header);
		test_mach_error("mach_msg_receive", kr, KERN_SUCCESS);
	});
	dispatch_source_set_cancel_handler(ds, ^{
		kern_return_t kr = mach_port_mod_refs(mach_task_self(), mp,
				MACH_PORT_RIGHT_RECEIVE, -1); // turns send right into dead name
		test_mach_error("mach_port_mod_refs", kr, KERN_SUCCESS);
	});
	dispatch_resume(ds);
	mach_msg_empty_send_t msg = { .header = {
		.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND),
		.msgh_size = sizeof(mach_msg_empty_send_t),
		.msgh_remote_port = mp,
	}};
	kr = mach_msg_send(&msg.header);
	test_mach_error("mach_msg_send", kr, KERN_SUCCESS);
	usleep(200000);
	dispatch_source_cancel(ds);
	dispatch_release(ds);
	test_long("DISPATCH_SOURCE_TYPE_MACH_RECV", received, 1);
	if (received > 1 ) {
		test_stop();
	}
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
}

#if DISPATCH_API_VERSION >= 20110201 && defined(MACH_NOTIFY_SEND_POSSIBLE) && \
		defined(MACH_SEND_NOTIFY)

#define TEST_SP_MSGCOUNT 11 // (2*qlim)+1

static bool
send_until_timeout(mach_port_t mp)
{
	kern_return_t kr;

	do {
		test_mach_debug_port(mp);
		mach_msg_empty_send_t msg = { .header = {
			.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND),
			.msgh_size = sizeof(mach_msg_empty_send_t),
			.msgh_remote_port = mp,
		}};
		kr = mach_msg(&msg.header,
				MACH_SEND_MSG|MACH_SEND_NOTIFY|MACH_SEND_TIMEOUT,
				msg.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
				MACH_PORT_NULL);
		if (kr == MACH_SEND_TIMED_OUT) {
			mach_msg_destroy(&msg.header);
			test_mach_error("mach_msg(MACH_SEND_MSG) timed out", kr,
					MACH_SEND_TIMED_OUT);
		} else {
			test_mach_error("mach_msg(MACH_SEND_MSG)", kr, KERN_SUCCESS);
			if (kr) test_stop();
		}
	} while (!kr && __sync_add_and_fetch(&sent, 1) < TEST_SP_MSGCOUNT);
	test_mach_debug_port(mp);
	return kr;
}

void
test_send_possible(void) // rdar://problem/8758200
{
	dispatch_source_t ds0, ds, dsp;
	kern_return_t kr;
	mach_port_t mp;

	sent = 0;
	received = 0;
	dispatch_group_enter(g);
	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
	test_mach_error("mach_port_allocate", kr, KERN_SUCCESS);
	test_mach_debug_port(mp);
	kr = mach_port_insert_right(mach_task_self(), mp, mp,
			MACH_MSG_TYPE_MAKE_SEND);
	test_mach_error("mach_port_insert_right", kr, KERN_SUCCESS);
	test_mach_debug_port(mp);
	ds0 = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, mp,
			DISPATCH_MACH_SEND_DEAD, dispatch_get_global_queue(0, 0));
	dispatch_source_set_registration_handler(ds0, ^{
		test_long("DISPATCH_MACH_SEND_DEAD registered",
				dispatch_source_get_handle(ds0), mp);
		test_mach_debug_port(mp);
	});
	dispatch_source_set_event_handler(ds0, ^{
		test_long("DISPATCH_MACH_SEND_DEAD delivered",
				dispatch_source_get_handle(ds0), mp);
		test_mach_debug_port(mp);
		dispatch_source_cancel(ds0);
		dispatch_release(ds0);
	});
	dispatch_source_set_cancel_handler(ds0, ^{
		test_long("DISPATCH_MACH_SEND_DEAD canceled",
				dispatch_source_get_handle(ds0), mp);
		test_mach_debug_port(mp);
		kern_return_t kr = mach_port_deallocate(mach_task_self(), mp);
		test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS);
		test_mach_debug_port(mp);
		dispatch_group_leave(g);
	});
	dispatch_resume(ds0);
	ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0,
			dispatch_get_global_queue(0, 0));
	dispatch_source_set_registration_handler(ds, ^{
		test_long("DISPATCH_SOURCE_TYPE_MACH_RECV registered",
				dispatch_source_get_handle(ds), mp);
		test_mach_debug_port(mp);
	});
	dispatch_source_set_event_handler(ds, ^{
		test_long("DISPATCH_SOURCE_TYPE_MACH_RECV delivered",
				dispatch_source_get_handle(ds), mp);
		kern_return_t kr;
		do {
			test_mach_debug_port(mp);
			usleep(10000); // simulate slow receiver
			mach_msg_empty_rcv_t msg = { .header = {
				.msgh_size = sizeof(mach_msg_empty_rcv_t),
				.msgh_local_port = mp,
			}};
			kr = mach_msg(&msg.header,
					MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, msg.header.msgh_size,
					msg.header.msgh_local_port, MACH_MSG_TIMEOUT_NONE,
					MACH_PORT_NULL);
			if (kr == MACH_RCV_TIMED_OUT) {
				test_mach_error("mach_msg(MACH_RCV_MSG) timed out", kr,
						MACH_RCV_TIMED_OUT);
			} else {
				test_mach_error("mach_msg(MACH_RCV_MSG)", kr, KERN_SUCCESS);
				if (kr) test_stop();
			}
		} while (!kr && __sync_add_and_fetch(&received, 1));
		test_mach_debug_port(mp);
	});
	dispatch_source_set_cancel_handler(ds, ^{
		test_long("DISPATCH_SOURCE_TYPE_MACH_RECV canceled",
				dispatch_source_get_handle(ds), mp);
		test_mach_debug_port(mp);
		kern_return_t kr = mach_port_mod_refs(mach_task_self(), mp,
				MACH_PORT_RIGHT_RECEIVE, -1); // trigger dead name notification
		test_mach_error("mach_port_mod_refs", kr, KERN_SUCCESS);
		test_mach_debug_port(mp);
	});
	dispatch_resume(ds);
	dsp = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, mp,
			DISPATCH_MACH_SEND_POSSIBLE, dispatch_get_global_queue(0, 0));
	dispatch_source_set_registration_handler(dsp, ^{
		test_long("DISPATCH_MACH_SEND_POSSIBLE registered",
				dispatch_source_get_handle(dsp), mp);
		if (!send_until_timeout(mp)) {
			dispatch_source_cancel(dsp); // stop sending
			dispatch_release(dsp);
		}
	});
	dispatch_source_set_event_handler(dsp, ^{
		test_long("DISPATCH_MACH_SEND_POSSIBLE delivered",
				dispatch_source_get_handle(dsp), mp);
		if (!send_until_timeout(mp)) {
			dispatch_source_cancel(dsp); // stop sending
			dispatch_release(dsp);
		}
	});
	dispatch_source_set_cancel_handler(dsp, ^{
		test_long("DISPATCH_MACH_SEND_POSSIBLE canceled",
				dispatch_source_get_handle(dsp), mp);
		test_mach_debug_port(mp);
		dispatch_source_cancel(ds); // stop receving
		dispatch_release(ds);
	});
	dispatch_resume(dsp);
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
	test_long("DISPATCH_SOURCE_TYPE_MACH_SEND", sent, TEST_SP_MSGCOUNT);
	test_long("DISPATCH_SOURCE_TYPE_MACH_RECV", received, TEST_SP_MSGCOUNT);
}

#else
#define test_send_possible()
#endif

static boolean_t
test_mig_callback(mach_msg_header_t *message __attribute__((unused)),
		mach_msg_header_t *reply)
{
	__sync_add_and_fetch(&received, 1);
	reply->msgh_remote_port = 0;
	return false;
}

void
test_mig_server_large_msg(void) // rdar://problem/8422992
{
	dispatch_source_t ds;
	kern_return_t kr;
	mach_port_t mp;

	received = 0;
	dispatch_group_enter(g);
	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
	test_mach_error("mach_port_allocate", kr, KERN_SUCCESS);
	kr = mach_port_insert_right(mach_task_self(), mp, mp,
			MACH_MSG_TYPE_MAKE_SEND);
	test_mach_error("mach_port_insert_right", kr, KERN_SUCCESS);
	ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0,
			dispatch_get_global_queue(0, 0));
	dispatch_source_set_event_handler(ds, ^{
		mach_msg_return_t r = dispatch_mig_server(ds, sizeof(mach_msg_header_t),
				test_mig_callback);
		test_mach_error("dispatch_mig_server", r, MACH_RCV_TOO_LARGE);
		dispatch_group_leave(g);
	});
	dispatch_source_set_cancel_handler(ds, ^{
		kern_return_t kr = mach_port_mod_refs(mach_task_self(), mp,
				MACH_PORT_RIGHT_RECEIVE, -1);
		test_mach_error("mach_port_mod_refs", kr, KERN_SUCCESS);
		kr = mach_port_deallocate(mach_task_self(), mp);
		test_mach_error("mach_port_deallocate", kr, KERN_SUCCESS);
		dispatch_group_leave(g);
	});
	dispatch_resume(ds);

	struct { mach_msg_header_t header; char payload[4096]; } msg = {
		.header = {
			.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND),
			.msgh_size = sizeof(mach_msg_header_t) + 4096,
			.msgh_remote_port = mp,
			.msgh_id = 0xfeedface,
		}
	};
	kr = mach_msg_send(&msg.header);
	test_mach_error("mach_msg_send", kr, KERN_SUCCESS);
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
	dispatch_group_enter(g);
	dispatch_source_cancel(ds);
	dispatch_release(ds);
	test_long("DISPATCH_SOURCE_TYPE_MACH_RECV", received, 0);
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
}

int
main(void)
{
	dispatch_test_start("Dispatch dead-name and send-possible notifications");

	dispatch_async(dispatch_get_global_queue(0, 0), ^{
		g = dispatch_group_create();
		test_dead_name();
		test_register_already_dead_name();
		test_receive_and_dead_name();
		test_send_possible();
		test_mig_server_large_msg();
		test_stop();
	});

	dispatch_main();

	return 0;
}
