Abstraction of semaphore to a class
This commit is contained in:
parent
1e3b38f777
commit
4f1e1fa1d7
8 changed files with 809 additions and 216 deletions
|
@ -1,12 +1,18 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "timing.h"
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
namespace IPC {
|
||||
|
||||
///\brief A class used for the exchange of statistics over shared memory.
|
||||
class statExchange {
|
||||
public:
|
||||
statExchange(char * _data);
|
||||
|
@ -27,18 +33,53 @@ namespace IPC {
|
|||
void connector(std::string name);
|
||||
std::string connector();
|
||||
private:
|
||||
///\brief The payload for the stat exchange
|
||||
/// - 8 byte - now (timestamp of last statistics)
|
||||
/// - 4 byte - time (duration of the current connection)
|
||||
/// - 4 byte - lastSecond (last second of content viewed)
|
||||
/// - 8 byte - down (Number of bytes received from peer)
|
||||
/// - 8 byte - up (Number of bytes sent to peer)
|
||||
/// - 16 byte - host (ip address of the peer)
|
||||
/// - 20 byte - streamName (name of the stream peer is viewing)
|
||||
/// - 20 byte - connector (name of the connector the peer is using)
|
||||
char * data;
|
||||
};
|
||||
|
||||
class semGuard {
|
||||
///\brief A class used for the abstraction of semaphores
|
||||
class semaphore {
|
||||
public:
|
||||
semGuard(sem_t * semaphore);
|
||||
~semGuard();
|
||||
semaphore();
|
||||
semaphore(const char * name, int oflag, mode_t mode, unsigned int value);
|
||||
~semaphore();
|
||||
operator bool() const;
|
||||
void open(const char * name, int oflag, mode_t mode = 0, unsigned int value = 0);
|
||||
int getVal() const;
|
||||
void post();
|
||||
void wait();
|
||||
bool tryWait();
|
||||
void close();
|
||||
void unlink();
|
||||
private:
|
||||
sem_t * mySemaphore;
|
||||
#ifdef __CYGWIN__
|
||||
HANDLE mySem;
|
||||
#else
|
||||
sem_t * mySem;
|
||||
#endif
|
||||
char * myName;
|
||||
};
|
||||
|
||||
#if !defined __APPLE__ && !defined __CYGWIN__
|
||||
///\brief A class used as a semaphore guard
|
||||
class semGuard {
|
||||
public:
|
||||
semGuard(semaphore thisSemaphore);
|
||||
~semGuard();
|
||||
private:
|
||||
///\brief The semaphore to guard.
|
||||
semaphore mySemaphore;
|
||||
};
|
||||
|
||||
#if !defined __APPLE__
|
||||
///\brief A class for managing shared memory pages.
|
||||
class sharedPage{
|
||||
public:
|
||||
sharedPage(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true);
|
||||
|
@ -50,20 +91,37 @@ namespace IPC {
|
|||
bool operator < (const sharedPage & rhs) const {
|
||||
return name < rhs.name;
|
||||
}
|
||||
void unmap();
|
||||
void close();
|
||||
#ifdef __CYGWIN__
|
||||
///\brief The handle of the opened shared memory page
|
||||
HANDLE handle;
|
||||
#else
|
||||
///\brief The fd handle of the opened shared memory page
|
||||
int handle;
|
||||
#endif
|
||||
///\brief The name of the opened shared memory page
|
||||
std::string name;
|
||||
///\brief The size in bytes of the opened shared memory page
|
||||
long long int len;
|
||||
///\brief Whether this class should unlink the shared memory upon deletion or not
|
||||
bool master;
|
||||
///\brief A pointer to the payload of the page
|
||||
char * mapped;
|
||||
};
|
||||
#else
|
||||
class sharedPage;
|
||||
#endif
|
||||
|
||||
#if !defined __APPLE__
|
||||
///\brief A class for managing shared files in the same form as shared memory pages
|
||||
#else
|
||||
///\brief A class for managing shared files.
|
||||
#endif
|
||||
class sharedFile{
|
||||
public:
|
||||
sharedFile(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true);
|
||||
sharedFile(const sharedPage & rhs);
|
||||
sharedFile(const sharedFile & rhs);
|
||||
~sharedFile();
|
||||
operator bool() const;
|
||||
void init(std::string name_, unsigned int len_, bool master_ = false, bool autoBackoff = true);
|
||||
|
@ -71,14 +129,23 @@ namespace IPC {
|
|||
bool operator < (const sharedFile & rhs) const {
|
||||
return name < rhs.name;
|
||||
}
|
||||
void unmap();
|
||||
///\brief The fd handle of the opened shared file
|
||||
int handle;
|
||||
///\brief The name of the opened shared file
|
||||
std::string name;
|
||||
///\brief The size in bytes of the opened shared file
|
||||
long long int len;
|
||||
///\brief Whether this class should unlink the shared file upon deletion or not
|
||||
bool master;
|
||||
///\brief A pointer to the payload of the file file
|
||||
char * mapped;
|
||||
};
|
||||
|
||||
#if defined __APPLE__ || defined __CYGWIN__
|
||||
#ifdef __APPLE__
|
||||
///\brief A class for handling shared memory pages.
|
||||
///
|
||||
///Uses shared files at its backbone, defined for portability
|
||||
class sharedPage: public sharedFile{
|
||||
public:
|
||||
sharedPage(std::string name_ = "", unsigned int len_ = 0, bool master_ = false, bool autoBackoff = true);
|
||||
|
@ -87,6 +154,15 @@ namespace IPC {
|
|||
};
|
||||
#endif
|
||||
|
||||
///\brief The server part of a server/client model for shared memory.
|
||||
///
|
||||
///The server manages the shared memory pages, and allocates new pages when needed.
|
||||
///
|
||||
///Pages are created with a basename + index, where index is in the range of 'A' - 'Z'
|
||||
///Each time a page is nearly full, the next page is created with a size double to the previous one.
|
||||
///
|
||||
///Clients should allocate payLen bytes at a time, possibly with the addition of a counter.
|
||||
///If no such length can be allocated, the next page should be tried, and so on.
|
||||
class sharedServer{
|
||||
public:
|
||||
sharedServer();
|
||||
|
@ -95,18 +171,33 @@ namespace IPC {
|
|||
~sharedServer();
|
||||
void parseEach(void (*callback)(char * data, size_t len, unsigned int id));
|
||||
operator bool() const;
|
||||
///\brief The amount of connected clients
|
||||
unsigned int amount;
|
||||
private:
|
||||
bool isInUse(unsigned int id);
|
||||
void newPage();
|
||||
void deletePage();
|
||||
///\brief The basename of the shared pages.
|
||||
std::string baseName;
|
||||
///\brief The length of each consecutive piece of payload
|
||||
unsigned int payLen;
|
||||
///\brief The set of sharedPage structures to manage the actual memory
|
||||
std::set<sharedPage> myPages;
|
||||
sem_t * mySemaphore;
|
||||
///\brief A semaphore that is locked upon creation and deletion of the page, to ensure no new data is allocated during this step.
|
||||
semaphore mySemaphore;
|
||||
///\brief Whether the payload has a counter, if so, it is added in front of the payload
|
||||
bool hasCounter;
|
||||
};
|
||||
|
||||
///\brief The client part of a server/client model for shared memory.
|
||||
///
|
||||
///The server manages the shared memory pages, and allocates new pages when needed.
|
||||
///
|
||||
///Pages are created with a basename + index, where index is in the range of 'A' - 'Z'
|
||||
///Each time a page is nearly full, the next page is created with a size double to the previous one.
|
||||
///
|
||||
///Clients should allocate payLen bytes at a time, possibly with the addition of a counter.
|
||||
///If no such length can be allocated, the next page should be tried, and so on.
|
||||
class sharedClient{
|
||||
public:
|
||||
sharedClient();
|
||||
|
@ -119,11 +210,17 @@ namespace IPC {
|
|||
void keepAlive();
|
||||
char * getData();
|
||||
private:
|
||||
///\brief The basename of the shared pages.
|
||||
std::string baseName;
|
||||
///\brief The shared page this client has reserved a space on.
|
||||
sharedPage myPage;
|
||||
sem_t * mySemaphore;
|
||||
///\brief A semaphore that is locked upon trying to allocate space on a page
|
||||
semaphore mySemaphore;
|
||||
///\brief The size in bytes of the opened page
|
||||
int payLen;
|
||||
///\brief The offset of the payload reserved for this client within the opened page
|
||||
int offsetOnPage;
|
||||
///\brief Whether the payload has a counter, if so, it is added in front of the payload
|
||||
bool hasCounter;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue