269 lines
8.8 KiB
C++
269 lines
8.8 KiB
C++
#pragma once
|
|
#include <set>
|
|
#include <string>
|
|
|
|
#include "defines.h"
|
|
#include "timing.h"
|
|
|
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
|
#include <windows.h>
|
|
#else
|
|
#include <semaphore.h>
|
|
#endif
|
|
|
|
#ifndef ACCESSPERMS
|
|
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO)
|
|
#endif
|
|
|
|
#define STAT_EX_SIZE 177
|
|
#define PLAY_EX_SIZE 2 + 6 * SIMUL_TRACKS
|
|
|
|
namespace IPC{
|
|
|
|
///\brief A class used for the exchange of statistics over shared memory.
|
|
class statExchange{
|
|
public:
|
|
statExchange(char *_data);
|
|
void now(long long int time);
|
|
long long int now();
|
|
void time(long time);
|
|
long time();
|
|
void lastSecond(long time);
|
|
long lastSecond();
|
|
void down(long long int bytes);
|
|
long long int down();
|
|
void up(long long int bytes);
|
|
long long int up();
|
|
void host(std::string name);
|
|
std::string host();
|
|
void streamName(std::string name);
|
|
std::string streamName();
|
|
void connector(std::string name);
|
|
std::string connector();
|
|
void crc(unsigned int sum);
|
|
char getSync();
|
|
void setSync(char s);
|
|
unsigned int crc();
|
|
uint32_t getPID();
|
|
std::string getSessId();
|
|
|
|
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)
|
|
/// - 100 byte - streamName (name of the stream peer is viewing)
|
|
/// - 20 byte - connector (name of the connector the peer is using)
|
|
/// - 4 byte - CRC32 of user agent (or zero if none)
|
|
/// - 1 byte sync (was seen by controller yes/no)
|
|
/// - (implicit 4 bytes: PID)
|
|
char *data;
|
|
};
|
|
|
|
///\brief A class used for the abstraction of semaphores
|
|
class semaphore{
|
|
public:
|
|
semaphore();
|
|
semaphore(const char *name, int oflag, mode_t mode = 0, unsigned int value = 0, bool noWait = false);
|
|
~semaphore();
|
|
operator bool() const;
|
|
void open(const char *name, int oflag, mode_t mode = 0, unsigned int value = 0, bool noWait = false);
|
|
int getVal() const;
|
|
void post();
|
|
void wait();
|
|
bool tryWait();
|
|
bool tryWaitOneSecond();
|
|
void close();
|
|
void abandon();
|
|
void unlink();
|
|
|
|
private:
|
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
|
///\todo Maybe sometime implement anything else than 777
|
|
static SECURITY_ATTRIBUTES getSecurityAttributes();
|
|
HANDLE mySem;
|
|
#else
|
|
sem_t *mySem;
|
|
#endif
|
|
unsigned int isLocked;
|
|
uint64_t lockTime;
|
|
std::string myName;
|
|
};
|
|
|
|
///\brief A class used as a semaphore guard
|
|
class semGuard{
|
|
public:
|
|
semGuard(semaphore *thisSemaphore);
|
|
~semGuard();
|
|
|
|
private:
|
|
///\brief The semaphore to guard.
|
|
semaphore *mySemaphore;
|
|
};
|
|
|
|
///\brief A class for managing shared files.
|
|
class sharedFile{
|
|
public:
|
|
sharedFile(const std::string &name_ = "", uint64_t len_ = 0, bool master_ = false, bool autoBackoff = true);
|
|
sharedFile(const sharedFile &rhs);
|
|
~sharedFile();
|
|
operator bool() const;
|
|
void init(const std::string &name_, uint64_t len_, bool master_ = false, bool autoBackoff = true);
|
|
void operator=(sharedFile &rhs);
|
|
bool operator<(const sharedFile &rhs) const{return name < rhs.name;}
|
|
void close();
|
|
void unmap();
|
|
bool exists();
|
|
///\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
|
|
uint64_t 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(__CYGWIN__) || defined(_WIN32)
|
|
void preservePage(std::string);
|
|
void releasePage(std::string);
|
|
#endif
|
|
|
|
#ifdef SHM_ENABLED
|
|
///\brief A class for managing shared memory pages.
|
|
class sharedPage{
|
|
public:
|
|
sharedPage(const std::string &name_ = "", uint64_t len_ = 0, bool master_ = false, bool autoBackoff = true);
|
|
sharedPage(const sharedPage &rhs);
|
|
~sharedPage();
|
|
operator bool() const;
|
|
void init(const std::string &name_, uint64_t len_, bool master_ = false, bool autoBackoff = true);
|
|
void operator=(sharedPage &rhs);
|
|
bool operator<(const sharedPage &rhs) const{return name < rhs.name;}
|
|
void unmap();
|
|
void close();
|
|
bool exists();
|
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
|
///\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
|
|
///\brief A class for handling shared memory pages.
|
|
/// Uses shared files at its backbone, defined for portability
|
|
class sharedPage : public sharedFile{
|
|
public:
|
|
sharedPage(const std::string &name_ = "", uint64_t len_ = 0, bool master_ = false, bool autoBackoff = true);
|
|
sharedPage(const sharedPage &rhs);
|
|
~sharedPage();
|
|
};
|
|
#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();
|
|
sharedServer(std::string name, int len, bool withCounter = false);
|
|
void init(std::string name, int len, bool withCounter = false);
|
|
~sharedServer();
|
|
void parseEach(void (*activeCallback)(char *data, size_t len, unsigned int id),
|
|
void (*disconCallback)(char *data, size_t len, unsigned int id) = 0);
|
|
char *getIndex(unsigned int id);
|
|
operator bool() const;
|
|
///\brief The amount of connected clients
|
|
unsigned int amount;
|
|
unsigned int connectedUsers;
|
|
void finishEach();
|
|
void abandon();
|
|
|
|
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::deque<sharedPage> myPages;
|
|
///\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();
|
|
sharedClient(const sharedClient &rhs);
|
|
sharedClient(std::string name, int len, bool withCounter = false);
|
|
void operator=(const sharedClient &rhs);
|
|
~sharedClient();
|
|
void write(char *data, int len);
|
|
void finish();
|
|
void keepAlive();
|
|
bool isAlive();
|
|
char *getData();
|
|
int getCounter();
|
|
bool countAsViewer;
|
|
|
|
private:
|
|
///\brief The basename of the shared pages.
|
|
std::string baseName;
|
|
///\brief The shared page this client has reserved a space on.
|
|
sharedPage myPage;
|
|
///\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;
|
|
};
|
|
|
|
class userConnection{
|
|
public:
|
|
userConnection(char *_data);
|
|
unsigned long getTrackId(size_t offset) const;
|
|
void setTrackId(size_t offset, unsigned long trackId) const;
|
|
unsigned long getKeynum(size_t offset) const;
|
|
void setKeynum(size_t offset, unsigned long keynum);
|
|
|
|
private:
|
|
char *data;
|
|
};
|
|
}// namespace IPC
|