/*
 * Copyright (c) 2015 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@
 */

#ifdef __BLOCKS__

#if __cplusplus < 201103L
#error Must build with C++11 or later
#endif

#if __has_feature(cxx_exceptions)
#error Must build without C++ exceptions
#endif

extern "C" {
#include "internal.h"
}

#if DISPATCH_DEBUG && DISPATCH_BLOCK_PRIVATE_DATA_DEBUG
#define _dispatch_block_private_data_debug(msg, ...) \
		_dispatch_debug("block_private[%p]: " msg, (this), ##__VA_ARGS__)
#else
#define _dispatch_block_private_data_debug(msg, ...)
#endif

#pragma mark -
#pragma mark _dispatch_block_create

// rdar://20766742 C++ helpers to enable block capture of vouchers and groups

struct dispatch_block_private_data_s {
	DISPATCH_BLOCK_PRIVATE_DATA_HEADER();
	static void* operator new(size_t) = delete;
	static void* operator new [] (size_t) = delete;
	explicit inline DISPATCH_ALWAYS_INLINE dispatch_block_private_data_s(
			dispatch_block_flags_t flags, voucher_t voucher,
			pthread_priority_t priority, dispatch_block_t block) noexcept :
			dbpd_magic(), dbpd_flags(flags), dbpd_atomic_flags(),
			dbpd_performed(), dbpd_priority(priority), dbpd_voucher(voucher),
			dbpd_block(block), dbpd_group(), dbpd_queue(), dbpd_thread()
	{
		// stack structure constructor, no releases on destruction
		_dispatch_block_private_data_debug("create, block: %p", dbpd_block);
	}
	inline DISPATCH_ALWAYS_INLINE dispatch_block_private_data_s(
			dispatch_block_private_data_s const &o) noexcept :
			dbpd_magic(DISPATCH_BLOCK_PRIVATE_DATA_MAGIC),
			dbpd_flags(o.dbpd_flags), dbpd_atomic_flags(), dbpd_performed(),
			dbpd_priority(o.dbpd_priority), dbpd_voucher(o.dbpd_voucher),
			dbpd_block(), dbpd_group(), dbpd_queue(), dbpd_thread()
	{
		// copy constructor, create copy with retained references
		if (dbpd_voucher) voucher_retain(dbpd_voucher);
		if (o.dbpd_block) dbpd_block = _dispatch_Block_copy(o.dbpd_block);
		_dispatch_block_private_data_debug("copy from %p, block: %p from %p",
				&o, dbpd_block, o.dbpd_block);
		if (!o.dbpd_magic) return; // No group in initial copy of stack object
		dbpd_group = _dispatch_group_create_and_enter();
	}
	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_queue) {
			((void (*)(os_mpsc_queue_t))_os_object_release_internal)(dbpd_queue);
		}
		if (dbpd_block) Block_release(dbpd_block);
		if (dbpd_voucher) voucher_release(dbpd_voucher);
	}
};

dispatch_block_t
_dispatch_block_create(dispatch_block_flags_t flags, voucher_t voucher,
		pthread_priority_t pri, dispatch_block_t block)
{
	struct dispatch_block_private_data_s dbpds(flags, voucher, pri, block);
	return _dispatch_Block_copy(^{
		// Capture stack object: invokes copy constructor (17094902)
		(void)dbpds;
		_dispatch_block_invoke_direct(&dbpds);
	});
}

extern "C" {
// The compiler hides the name of the function it generates, and changes it if
// we try to reference it directly, but the linker still sees it.
extern void DISPATCH_BLOCK_SPECIAL_INVOKE(void *)
#ifdef __linux__
		asm("___dispatch_block_create_block_invoke");
#else
		asm("____dispatch_block_create_block_invoke");
#endif
void (*_dispatch_block_special_invoke)(void*) = DISPATCH_BLOCK_SPECIAL_INVOKE;
}

#endif // __BLOCKS__
