/***************************************************************************
 *   Copyright (C) 2004 by EVER Sp. z o.o.                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef CSHMEM_H
#define CSHMEM_H

#include <iostream>
#include <cstdlib>

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#include "common.h"

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
 /* union semun is defined by including <sys/sem.h> */
#else
    #ifndef __FreeBSD__
     /* according to X/OPEN we have to define it ourselves */
    union semun {
	int val;                    /* value for SETVAL */
        struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
	unsigned short int *array;  /* array for GETALL, SETALL */
        struct seminfo *__buf;      /* buffer for IPC_INFO */
	};
    #endif/*__FreeBSD__*/
#endif


#define SHM_SUCCESS	( 0)
#define SHM_FAILURE	(-1)

class CShMem
{
private:
/*	union semun {
      int val;                  // value for SETVAL
      struct semid_ds *buf;     // buffer for IPC_STAT, IPC_SET
      unsigned short *array;    // array for GETALL, SETALL
                                // Linux specific part:
      struct seminfo *__buf;    // buffer for IPC_INFO
	};
*/	/* internal variables */
	key_t	shm_key, sem_key;
	size_t	shm_size;
	char	*segptr;
	bool	isat, isid, isopened;
	/* shm creator for initialized constructor */
	int create();
	/* semaphore handling functions */
	int createsem(key_t skey);
	int opensem(key_t skey);
	int closesem();
	bool issemlocked();
	bool locksem();
	bool locksem(bool wait);
	bool unlocksem();
	
public:
	/* internal variables */
	int		shm_id, sem_id;
	/* class constructor/destructor */
	CShMem();
	CShMem(key_t smkey, size_t smsize) {
		shm_key = smkey;
		shm_size = smsize;
		shm_id = sem_id = 0;
		isat=isid=isopened=false;
		create();
	};
	~CShMem();
	
	/* create or open memory segment */
	int createkey(char *pathname, int proj_id);
	int create(key_t smkey, size_t smsize);
	int create(size_t smsize);
	int open(key_t smkey, size_t smsize);
	int open(size_t smsize);
	int read(void *smbuf, size_t offset, size_t len);
	void *read(size_t offset);
	int read(void *smbuf, size_t offset, size_t len, bool wait);
	void *read(size_t offset, bool wait);
	int write(void *smbuf, size_t offset, size_t len);
	int write(void *smbuf, size_t offset, size_t len, bool wait);
	int clear();
	int close();
};

#endif/*CSHMEM_H*/

