#ifndef SHM_H
#define SHM_H

#include <stdlib.h>

class ShmApi;
class ShmSemApi;
typedef int ShmPlace;
typedef int ShmSlot;

#define SHM_MAX_SLOTS 100
#define SHM_NULL      -1

class ShmSem {
private:
    ShmSemApi *_api;

public:
    void post();
    bool wait(int ms);
    bool trywait();
    void takeOwnership();

public:
    ShmSem(const char *n, bool owner);
    ~ShmSem();
};

class Shm
{
private:
    ShmApi *_shm_api;

public:
    ShmPlace alloc(size_t mem);
    void free(ShmPlace place);
    void lock();
    void unlock();

public:
    ShmPlace slot(ShmSlot s);
    void setSlot(ShmSlot s, ShmPlace pl);

public:
    ShmSem *sem(const char *name, bool owner);

public:
    bool isValid();

public:
    const char *name();

public:
    void *ref(int place);

public:
    void takeOwnership();

public:
    void info(int &usage, int &free_depth, int &free_size, int &item_depth, int &item_size, double &usage_factor);

public:
    Shm(const char *name, size_t bytes, bool owner);
    ~Shm();
};

template <class T> inline void ref(Shm *shm, int place, T **p)
{
    *p = reinterpret_cast<T *>(shm->ref(place));
}

#endif // SHM_H
