/**
{file:
	{name: LmiAsync.h}
	{description: Async execution. }
	{copyright:
		(c) 2013-2017 Vidyo, Inc.,
		433 Hackensack Avenue,
		Hackensack, NJ  07601.

		All rights reserved.

		The information contained herein is proprietary to Vidyo, Inc.
		and shall not be reproduced, copied (in whole or in part), adapted,
		modified, disseminated, transmitted, transcribed, stored in a retrieval
		system, or translated into any language in any form by any means
		without the express written consent of Vidyo, Inc.
		                  ***** CONFIDENTIAL *****
	}
}
*/
#ifndef LMI_ASYNC_H_
#define LMI_ASYNC_H_

#include <Lmi/Os/LmiThreadPool.h>
#include <Lmi/Os/LmiProperties.h>

LMI_BEGIN_EXTERN_C

struct LmiAsyncImpl_;
typedef struct LmiAsyncImpl_ LmiAsyncImpl;
Declare_LmiSharedPtr(LmiAsyncImpl)
Declare_LmiSharedPtrWrapper(LmiAsync, LmiAsyncImpl)
Declare_LmiWeakPtrWrapper(LmiAsyncHandle, LmiAsync, LmiAsyncImpl)

/**
{type visibility="private":
	{name: LmiAsync}
	{parent: Os}
	{include: Lmi/Os/LmiAsync.h}
	{description: Run function "asynchronously". The function will be run on a separate thread. }
}
*/

/**
{callback visibility="private":
	{name: LmiAsyncFunction}
	{parent: LmiAsync}
	{description: Function that will be called asynchronously on a spawned thread. }
	{prototype: void (*LmiAsyncFunction)(LmiProperties* properties)}
	{parameter: {name: properties} {description: Properties that were set when the request was sent with LmiAsyncRun(). }}
}
*/
typedef void (*LmiAsyncFunction)(LmiProperties* properties);

/**	{function visibility="private":
		{name: LmiAsyncInitialize}
		{parent: LmiAsync}
		{description: Initializes tables and data structures required for Async class to operate.}
		{prototype:	LmiBool LmiAsyncInitialize(void)}
		{return: {code:	LMI_TRUE} on success, or {code:	LMI_FALSE} on failure.}
		{note: This	function must be called	prior to any memory	related	operation.}
	}
*/
LmiBool	LmiAsyncInitialize(void);

/**	{function visibility="private":
		{name: LmiAsyncUninitialize}
		{parent: LmiAsync}
		{description: Uninitializes	tables and data	structures.}
		{prototype:	void LmiAsyncUninitialize(void)}
	}
*/
void LmiAsyncUninitialize(void);

/**
{function visibility="private":
	{name: LmiAsyncConstruct}
	{parent: LmiAsync}
	{description: Initialize an instance of LmiAsync}
	{prototype: LmiAsync* LmiAsyncConstruct(LmiAsync* async, LmiSizeT numThreads, LmiSizeT queueSize, const char *poolName, LmiAllocator* alloc)}
	{parameter: {name: async} {description: Pointer to the LmiAsync object to construct.}}
	{parameter: {name: numThreads} {description: Number of threads to run. }}
	{parameter: {name: queueSize} {description: Size of the queue. }}
	{parameter: {name: poolName} {description: Optional name of thread pool. Can be NULL. }}
	{parameter: {name: alloc} {description: allocator}}
	{return: Properly initialized object or NULL on failure.}
}
*/
LmiAsync* LmiAsyncConstruct(LmiAsync* async, LmiSizeT numThreads, LmiSizeT queueSize, const char *poolName, LmiAllocator* alloc);

/**
{function visibility="private":
	{name: LmiAsyncDestruct}
	{parent: LmiAsync}
	{description: Destruct an instance of LmiAsync. This may block until there are no more threads running.}
	{prototype: void LmiAsyncDestruct(LmiAsync* async)}
	{parameter: {name: async} {description: Pointer to the LmiAsync object to destruct.}}
}
*/
void LmiAsyncDestruct(LmiAsync* async);

/**
{function visibility="private":
	{name: LmiAsyncRun}
	{parent: LmiAsync}
	{description: Schedule an async function to be executed on a separate thread. }
	{prototype: LmiBool LmiAsyncRun(LmiAsync* async, LmiAsyncFunction function, LmiProperties* properties, LmiBool useMainThread)}
	{parameter: {name: async} {description: Pointer to the LmiAsync object.}}
	{parameter: {name: function} {description: Function to be executed }}
	{parameter: {name: properties} {description: Properties to be passed to the function}}
	{parameter: {name: useMainThread} {description: Attempt to run the function on the main thread of the application. }}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
	{note: useMainThread may not be available on every platform in which case it will execute in a normal thread. }
}
*/
LmiBool LmiAsyncRun(LmiAsync* async, LmiAsyncFunction function, LmiProperties* properties, LmiBool useMainThread);

LMI_END_EXTERN_C

#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
#include "LmiAsyncInline.h"
#endif

#endif /* LMI_ASYNC_H_ */
