/*
 * 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>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#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;
}
