/*******************************************************************************
 * Copyright (c) 2005, 2007 Intel Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Hoang M Nguyen, Intel - Initial API and Implementation
 *    IBM - Portions of old RAC code (brought over by Hoang M Nguyen)
 *
 * $Id: TransportSupportSharedMemExt.c,v 1.13 2007/11/21 15:24:32 ialelekov Exp $
 *
 *******************************************************************************/ 


#include "RAComm.h"
#include "RAShm.h"

#define __TPTPCOMMON_H__

#include "tptp/TransportSupportSharedMem.h"

#include "tptp/NoLog.h"

//We need to reference this stop flushing routine.
extern tptp_int32 ra_setShmAttachCount(ra_shm_handle_t *, tptp_int32);
extern tptp_int32 ra_stopFlusher(ra_shm_handle_t *);
extern int ossRamboClose(ra_shm_handle_t*);
extern tptp_int32 ossRamboDetach(ra_shm_handle_t *);

/**
 *********************************************************
 *
 * @brief
 *    Open an IPC memory resource.
 *
 * @param  pMemName
 *              the name of shared memory resource
 *
 * @param  pBlockInfo
 *              the info of the returned shared memory map
 *
 * @return
 *    0 - Success
 *    nonzero - Error.
 *********************************************************/
int ipcMemOpen(
      const char * pMemName,
	  mem_map_block_ptr_t pBlockInfo) 
{
	int    rc = 0 ;

	ra_shm_handle_t *pShmHdl = (ra_shm_handle_t *) NULL ;
			
	rc =  ra_attachToShm((char *) pMemName, & pShmHdl);

	TPTP_LOG_DEBUG_MSG2("ipcMemOpen:  mem_name(%s) rc(%d)", pMemName, rc) ;

	if (rc == 0)
	{
		pBlockInfo->pRamboBlock = (LPVOID) pShmHdl ;
		TPTP_LOG_DEBUG_MSG2("ipcMemOpen:  block(%x) handle(%x)", pBlockInfo, pBlockInfo->pRamboBlock) ;
	}

	return ( rc ) ;

}

int isMemOpen (mem_map_block_ptr_t pBlockInfo) {
	return (pBlockInfo != NULL && pBlockInfo->pRamboBlock != NULL) ? 1 : 0;
}


/**
 *********************************************************
 *
 * @brief
 *    Stop reading from the given IPC memory resource.
 *
 * @param  pBlockInfo
 *              the info of the shared memory map to stop reading
 *
 * @return
 *    0 - Success
 *    nonzero - Error.
 *********************************************************/


int ipcStopFlushing(mem_map_block_ptr_t pBlockInfo)
{
	int    rc = 0 ;

	ra_shm_handle_t *pShmHdl = (ra_shm_handle_t *) pBlockInfo->pRamboBlock ;

	//It would be nice if we could call ra_stopFlushingShm
	//But that routine is set up to free the handle... which will crash
	//the flusher rather than stopping it!
	//By setting the attach count to 1 it will stop the flushing thread.
	if (pShmHdl != NULL) {
		rc = ra_setShmAttachCount(pShmHdl, 1);
	}

	return ( rc ) ;
}

int ipcStopFlusher(mem_map_block_ptr_t pBlockInfo)
{
	int    rc = 0 ;

	ra_shm_handle_t *pShmHdl = (ra_shm_handle_t *) pBlockInfo->pRamboBlock ;

	if (pShmHdl != NULL) {
		rc = ra_stopFlusher(pShmHdl);
	}

	return ( rc ) ;
}

int ipcCloseMem(mem_map_block_ptr_t pBlockInfo)
{
	int    rc = 0 ;

	ra_shm_handle_t *pShmHdl = (ra_shm_handle_t *) pBlockInfo->pRamboBlock ;
	if (pShmHdl != NULL) {
		rc = ossRamboClose(pShmHdl);
	}

	return ( rc ) ;
}

int ipcMemDetach (mem_map_block_ptr_t pBlockInfo) {
	int r;
	ra_shm_handle_t *pShmHdl = (ra_shm_handle_t*) pBlockInfo->pRamboBlock;
	if (pShmHdl == NULL) {
		return -1;
	}
	
	r = ossRamboDetach (pShmHdl);
	
	pBlockInfo->pRamboBlock = NULL;
	
	return r;
}
