/********************************************************************************
// $Id:  $
//
//	file name   :	$Source:  $
//
//	purpose:	QNX NT adapter
//
//
//	author(s):	Ian Archer
//
//	date started:	march 2008
//
//	Licensed Materials - Property of IBM
//	© Copyright IBM Corporation 2002, 2008. All Rights Reserved.
//
//
// ---------------------------------------------------------------
//|							  RiCOSQNX.h                          |
// ---------------------------------------------------------------
*********************************************************************************/

#ifndef RiCOSQNX_H
#define RiCOSQNX_H "$Id:  $"

#include <pthread.h>
#include <mqueue.h>
#include <semaphore.h>

#include <oxf/RiCTypes.h>
#include <oxf/RiCQueue.h>

#ifdef __cplusplus
extern "C" {
#endif
#include <omcom/omsdata.h>

#define PRIORITY_HIGH 60
#define PRIORITY_NORMAL 40
#define PRIORITY_LOW 10 

	typedef unsigned long RiCOSResult;
	typedef unsigned long RiCOSHandle;
	typedef void (*RiCOSTaskEndCallBack)(void *);
	typedef void (*RiCOS_dispatchfunc)(RiCSData *);

	/***************************************************/
	/****				RiCOSEventFlag				****/
	/***************************************************/
	typedef struct RiCQNXEventFlag
	{
		sem_t	hEventFlag;
	} RiCQNXEventFlag ;
	typedef RiCQNXEventFlag RiCOSEventFlag;


	/***************************************************/
	/****				RiCOSMutex					****/
	/***************************************************/
	typedef struct RiCQNXMutex
	{
		pthread_mutex_t	hMutex;
	} RiCQNXMutex ;
	typedef RiCQNXMutex RiCOSMutex ;

	/********************/
#define RiCOSMutex_lock(me) (((me) == NULL) ? RiCOSFailure : (pthread_mutex_lock(&((me)->hMutex))) == 0 ? RiCOSSuccess : RiCOSFailure)

	/********************/
#define RiCOSMutex_free(me) (((me) == NULL) ? RiCOSSuccess : (pthread_mutex_unlock(&((me)->hMutex))) == 0 ? RiCOSSuccess : RiCOSFailure)

	/***************************************************/
	/****				RiCOSTask					****/
	/***************************************************/
	typedef unsigned (* start_addr_t) (void *);

	typedef struct RiCQNXTask
	{
		void (*cbkfunc)(void *);
		void      * cbkparam;
		pthread_t	hThread ;
		int			isWrapperThread;
		RiCBoolean	endOSTaskInCleanup;	/* TRUE means that the os thread is ended as part of this object's destruction */
		sem_t		suspEventFlag;
		RiCBoolean	suspend;
	} RiCQNXTask;
	typedef RiCQNXTask RiCOSTask ;


	/***************************************************/
	/****				RiCOSTimer					****/
	/***************************************************/
	typedef struct RiCQNXTimer
	{
		void (*cbkfunc)(void *);
		pthread_t hThread;			/* The timeTick thread */
		timeUnit m_Time ;
		void *param;
	} RiCQNXTimer ;
	typedef RiCQNXTimer RiCOSTimer  ;


	/***************************************************/
	/****			RiCOSMessageQueue				****/
	/***************************************************/
	#ifdef RIC_DISTRIBUTED_SYSTEM
#define	QNX_DOX_MAX_MSGS			(100)			// Maximum number of messages in the queue
#define	QNX_DOX_MSG_LEN				(128)			// Maximum length of a message

		typedef struct RiCQNXMessageQueue {
			/* QNX message queue that represents the distribited queue */
			mqd_t m_hQueue;

			/*
			Whether to distribute the queue or not (allow it to receive messages
			from different address spaces)
			*/
			RiCBoolean m_ToDistributeQueue;

			/* The name published in the resource manager and in the name service */
			RiCString m_QueuePublishedName;

			/* The ID of the queue in the name service */
			RhpInteger m_RegisteredId;

			/* Data saved during a pend */
			char * m_pSavedData;

			/* Maximum size of the queue */
			unsigned int	m_QueueSize;
		}RiCQNXMessageQueue;
	#else
		typedef struct RiCQNXMessageQueue
		{
			RiCQueue 	m_baseRiCQueue;
			RiCQNXMutex	m_QueueMutex;
			RiCQNXEventFlag m_QueueEventFlag;
		} RiCQNXMessageQueue ;
		/* check if the message queue is empty */
		#define RiCOSMessageQueue_isEmpty(me) (((me) == 0) ? RiCTRUE : RiCQueue_isEmpty(&((me)->m_baseRiCQueue)))
	#endif

	typedef RiCQNXMessageQueue RiCOSMessageQueue;

	/***************************************************/
	/****				RiCOSSemaphore				****/
	/***************************************************/
	typedef struct RiCQNXSemaphore
	{
		sem_t hSemaphore;
	} RiCQNXSemaphore ;
	typedef RiCQNXSemaphore RiCOSSemaphore;

/***************************************************/
/* Memory management                               */
/***************************************************/
typedef void * (* RiCQNXOSAllocMemP_t)(const size_t requestedSize);
typedef void (* RiCQNXOSFreeMemP_t)(const void *const contents);

/* Inline calls to alloc and free routines */
#define RiCQNXOSAllocMem(reqSize)	(RiCQNXOSMemoryAllocator(reqSize))
#define	RiCQNXOSFreeMem(memPtr)		(RiCQNXOSMemoryDeallocator(memPtr))

extern RiCQNXOSAllocMemP_t RiCQNXOSMemoryAllocator;
extern RiCQNXOSFreeMemP_t  RiCQNXOSMemoryDeallocator;

/* Point malloc and free at our routines if debugging memory*/
#ifdef	DEBUG_MEMORY
#define malloc(x)	RiCQNXOSAllocMem(x)
#define free(x)		RiCQNXOSFreeMem(x)
#endif

#ifdef _OMINSTRUMENT

	/***************************************************/
	/****				RiCOSSocket					****/
	/***************************************************/
	typedef struct RiCQNXSocket
	{
		int theSock;
	} RiCQNXSocket ;
	typedef RiCQNXSocket RiCOSSocket;


	/***************************************************/
	/****			RiCOSConnectionPort				****/
	/***************************************************/

	typedef void (*RiCOSConnectionPortDispatchFunc)(RiCSData *);

	typedef struct RiCQNXConnectionPort
	{
		RiCOSMutex m_SendMutex ;
		int m_Connected;
		RiCOSConnectionPortDispatchFunc m_dispatchfunc;
		pthread_t hSocketHandleThread;
		RiCOSSocket m_Socket;
		int m_ShouldWaitForAck;
		RiCOSEventFlag m_AckEventFlag;
		int m_NumberOfMessagesBetweenAck;
	} RiCQNXConnectionPort ;
	typedef RiCQNXConnectionPort RiCOSConnectionPort;

#endif /* _OMINSTRUMENT */

#ifdef __cplusplus
}
#endif

#endif /* RiCOSQNX_H */

/*
// $Log:  $
*/
