sharedmem: config, sethostname call freesharedmemory and call setupmulti, freesharedmemoy(nonstatic) also cleans up member variables to make it consistent with shm, sharedmemory pointer set to 0 in non static free shared memory to be able to continue within application, sethostname frees memory only if detectors found in shm, add calls addmultipledetectors, replace replaces a detector in sls detector level, should also take lines in config file that has comments in between while ignoring the comments, sethostname in slsdetector also updates client, adding object in sls when creating new shm complains if shm existed and must delete again, removed remove commands

This commit is contained in:
maliakal_d 2018-06-27 15:38:03 +02:00
parent a0016cb005
commit 95254619c6
8 changed files with 204 additions and 171 deletions

View File

@ -36,12 +36,7 @@ multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
thisMultiDetector(0),
client_downstream(false),
threadpool(0) {
if (initSharedMemory(verify))
// shared memory just created, so initialize the structure
initializeDetectorStructure();
initializeMembers(verify);
if (update)
updateUserdetails();
setupMultiDetector(verify, update);
}
@ -70,6 +65,15 @@ bool multiSlsDetector::isMultiSlsDetectorClass() {
return true;
}
void multiSlsDetector::setupMultiDetector(bool verify, bool update) {
if (initSharedMemory(verify))
// shared memory just created, so initialize the structure
initializeDetectorStructure();
initializeMembers(verify);
if (update)
updateUserdetails();
}
std::string multiSlsDetector::concatResultOrPos(std::string (slsDetector::*somefunc)(int), int pos) {
if (pos >= 0 && pos < detectors.size()) {
return (detectors[pos]->*somefunc)(pos);
@ -637,21 +641,34 @@ void multiSlsDetector::freeSharedMemory(int multiId) {
void multiSlsDetector::freeSharedMemory() {
// should be done before the detector list is deleted
clearAllErrorMask();
// single detector vector
// clear sls detector vector shm
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
(*it)->freeSharedMemory();
delete (*it);
}
detectors.clear();
// multi detector
// clear multi detector shm
if (sharedMemory) {
sharedMemory->UnmapSharedMemory(thisMultiDetector);
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
sharedMemory = 0;
}
thisMultiDetector = 0;
// clear zmq vector
for (vector<ZmqSocket*>::const_iterator it = zmqSocket.begin(); it != zmqSocket.end(); ++it) {
delete(*it);
}
zmqSocket.clear();
// zmq
destroyThreadPool();
client_downstream = false;
}
@ -683,8 +700,9 @@ std::string multiSlsDetector::getUserDetails() {
bool multiSlsDetector::initSharedMemory(bool verify) {
// clear
if (sharedMemory)
if (sharedMemory) {
delete sharedMemory;
}
thisMultiDetector = 0;
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
@ -705,6 +723,7 @@ bool multiSlsDetector::initSharedMemory(bool verify) {
MULTI_SHMVERSION, thisMultiDetector->shmversion);
sharedMemory->UnmapSharedMemory(thisMultiDetector);/** is this unncessary? */
delete sharedMemory;/** is this unncessary? */
sharedMemory = 0;
throw SharedMemoryException();
}
} else {
@ -713,6 +732,8 @@ bool multiSlsDetector::initSharedMemory(bool verify) {
created = true;
} catch(...) {
sharedMemory->RemoveSharedMemory();
delete sharedMemory;/** is this unncessary? */
sharedMemory = 0;/** is this unncessary? */
thisMultiDetector = 0;
throw;
}
@ -911,6 +932,22 @@ std::string multiSlsDetector::exec(const char* cmd) {
void multiSlsDetector::setHostname(const char* name) {
// this check is there only to allow the previous detsizechan command
if (thisMultiDetector->numberOfDetectors) {
cprintf(RED, "Warning: There are already detector(s) in shared memory."
"Freeing Shared memory now.\n");
freeSharedMemory();
setupMultiDetector();
}
addMultipleDetectors(name);
}
string multiSlsDetector::getHostname(int pos) {
return concatResultOrPos(&slsDetector::getHostname, pos);
}
void multiSlsDetector::addMultipleDetectors(const char* name) {
size_t p1 = 0;
string temp = string(name);
size_t p2 = temp.find('+', p1);
@ -931,13 +968,6 @@ void multiSlsDetector::setHostname(const char* name) {
setOnline();
}
string multiSlsDetector::getHostname(int pos) {
return concatResultOrPos(&slsDetector::getHostname, pos);
}
void multiSlsDetector::addSlsDetector (std::string s) {
#ifdef VERBOSE
cout << "Adding detector " << s << endl;
@ -956,8 +986,7 @@ void multiSlsDetector::addSlsDetector (std::string s) {
// get type by connecting
detectorType type = slsDetector::getDetectorType(s.c_str(), DEFAULT_PORTNO);
if (type == GENERIC) {
cout << "Detector " << s << "does not exist in shared memory "
"and could not connect to it to determine the type!" << endl;
cout << "Could not connect to Detector " << s << " to determine the type!" << endl;
setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED);
appendNotAddedList(s.c_str());
return;
@ -970,9 +999,7 @@ void multiSlsDetector::addSlsDetector (std::string s) {
detectors.push_back(sdet);
thisMultiDetector->numberOfDetectors = detectors.size();
detectors[pos]->setHostname(s.c_str());
if (detectors[pos]->setOnline() ==ONLINE_FLAG)
detectors[pos]->updateDetector();
detectors[pos]->setHostname(s.c_str()); // also updates client
thisMultiDetector->dataBytes += detectors[pos]->getDataBytes();
thisMultiDetector->dataBytesInclGapPixels += detectors[pos]->getDataBytesInclGapPixels();
@ -1386,16 +1413,9 @@ int multiSlsDetector::exitServer() {
}
int multiSlsDetector::readConfigurationFile(string const fname) {
{
clearAllErrorMask();
freeSharedMemory();
if (initSharedMemory())
// shared memory just created, so initialize the structure
initializeDetectorStructure();
initializeMembers(true); // also deletes zmq objects and destroys threadpool
updateUserdetails();
}
freeSharedMemory();
setupMultiDetector();
multiSlsDetectorClient* cmd;
@ -1419,9 +1439,12 @@ int multiSlsDetector::readConfigurationFile(string const fname) {
sargval = "0";
getline(infile, str);
++iline;
str.erase(str.find('#'), string::npos);
// remove comments that come after
if (str.find('#') != string::npos)
str.erase(str.find('#'));
#ifdef VERBOSE
std::cout << str << std::endl;
std::cout << "string:" << str << std::endl;
#endif
if (str.length() < 2) {
#ifdef VERBOSE

View File

@ -21,7 +21,7 @@ class ZmqSocket;
#define MULTI_SHMVERSION 0x180625
#define SHORT_STRING_LENGTH 50
#define DATE_LENGTH 29
#define DATE_LENGTH 30
class multiSlsDetector : public slsDetectorUtils {
@ -244,6 +244,14 @@ public:
*/
bool isMultiSlsDetectorClass();
/**
* Creates/open shared memory, initializes detector structure and members
* Called by constructor/ set hostname / read config file
* @param verify true to verify if shared memory version matches existing one
* @param update true to update last user pid, date etc
*/
void setupMultiDetector(bool verify = true, bool update = true);
/**
* If specific position, then provide result with that detector at position pos
* else concatenate the result of all detectors
@ -501,6 +509,8 @@ public:
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedMultiSlsDetector structure
* Clears all the vectors and destroys threadpool to bring
* object back to state before object creation amap
*/
void freeSharedMemory();
@ -525,6 +535,13 @@ public:
*/
std::string getHostname(int pos = -1);
/**
* Appends detectors to the end of the list in shared memory
* Connects to them to set up online flag
* @param name concatenated hostname of the sls detectors to be appended to the list
*/
void addMultipleDetectors(const char* name);
using slsDetectorBase::getDetectorType;
/**

View File

@ -55,7 +55,7 @@ public:
// sls pos scanned
iv=sscanf(argv[0],"%d:%s", &pos, cmd); \
if (iv != 2 ) \
pos = -1; \
pos = -1; \
if (iv == 2 && pos >= 0) { \
argv[0] = cmd; \
cout << pos << ":" ; \
@ -79,19 +79,8 @@ public:
multiSlsDetector::freeSharedMemory(id); \
return; \
} \
// (sls level): give error message
// (multi level): free before calling multiSlsDetector constructor
else if (scmd == "hostname") { \
if (pos != -1) { \
cout << "pos " << pos << "not allowed for hostname. " \
"Only from multi detector level." << endl; \
return; \
} \
else \
multiSlsDetector::freeSharedMemory(id); \
} \
// get user details without verify sharedMultiSlsDetector version
else if ((scmd == "userdetails") && (action==slsDetectorDefs::GET_ACTION)) {\
else if ((scmd == "user") && (action==slsDetectorDefs::GET_ACTION)) { \
verify = false; \
update = false; \
myDetector=NULL; \
@ -123,7 +112,7 @@ public:
return; \
}; \
cout<<"id:"<<id<<" pos:"<<pos<<endl;
//cout<<"id:"<<id<<" pos:"<<pos<<endl;
// call multi detector command line
myCmd=new multiSlsDetectorCommand(myDetector); \
answer=myCmd->executeLine(argc, argv, action, pos); \

View File

@ -81,18 +81,7 @@ slsDetector::slsDetector(int multiId, int id, bool verify, multiSlsDetector* m)
offset(0) {
/* called from multi constructor to populate structure,
* so sls shared memory will be opened, not created */
// ensure shared memory is existing
SharedMemory* shm = new SharedMemory(multiId, id);
if (!SharedMemory::IsExisting(shm->GetName())) {
cprintf(YELLOW BOLD,"Warning: Corrupted shared memory. It should have been "
"created before! %s.\n", shm->GetName().c_str());
delete shm; /* is this necessary ?*/
throw SharedMemoryException();
}
delete shm;
// getDetectorType Froom shm will check if it was already existing
detectorType type = getDetectorTypeFromShm(multiId, verify);
initSharedMemory(false, type, multiId, verify);
initializeMembers();
@ -411,18 +400,29 @@ void slsDetector::freeSharedMemory() {
sharedMemory->UnmapSharedMemory(thisDetector);
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
sharedMemory = 0;
}
thisDetector = 0;
}
string slsDetector::getUserDetails() {
cprintf(RED, "Error: Get User details should not be called at this level\n");
return string("");
}
void slsDetector::setHostname(const char *name) {
setTCPSocket(string(name));
if (thisDetector->onlineFlag == ONLINE_FLAG)
updateDetector();
}
string slsDetector::getHostname(int pos) {
return string(thisDetector->hostname);
}
void slsDetector::addMultipleDetectors(const char* name) {
cprintf(RED, "Error: Add Multiple Detectors should not be called at this level\n");
}
void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
bool verify) {
@ -441,6 +441,8 @@ void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
thisDetector = (sharedSlsDetector*)sharedMemory->CreateSharedMemory(sz);
} catch(...) {
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
sharedMemory = 0;
thisDetector = 0;
throw;
}
@ -454,6 +456,7 @@ void slsDetector::initSharedMemory(bool created, detectorType type, int multiId,
multiId, detId, SLS_SHMVERSION, thisDetector->shmversion);
sharedMemory->UnmapSharedMemory(thisDetector); /** is this unncessary? */
delete sharedMemory;/** is this unncessary? */
sharedMemory = 0;
throw SharedMemoryException();
}
}
@ -830,8 +833,10 @@ void slsDetector::initializeMembers() {
chanregs = (int*)(goff + thisDetector->chanoff);
gain = (int*)(goff + thisDetector->gainoff);
offset = (int*)(goff + thisDetector->offsetoff);
if (thisReceiver)
if (thisReceiver) {
delete thisReceiver;
thisReceiver = 0;
}
thisReceiver = new receiverInterface(dataSocket);
@ -1254,10 +1259,10 @@ slsReceiverDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, b
// open, map, verify version, get type
sdet = (sharedSlsDetector*)shm->OpenSharedMemory(sz);
if (verify && thisDetector->shmversion != SLS_SHMVERSION) {
if (verify && sdet->shmversion != SLS_SHMVERSION) {
cprintf(RED, "Single shared memory (%d-%d:)version mismatch "
"(expected 0x%x but got 0x%x)\n",
multiId, detId, SLS_SHMVERSION, thisDetector->shmversion);
multiId, detId, SLS_SHMVERSION, sdet->shmversion);
shm->UnmapSharedMemory(sdet); /** is this unncessary? */
delete shm;/** is this unncessary? */
throw SharedMemoryException();

View File

@ -475,12 +475,18 @@ public:
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedSlsDetector structure
* If this is called, must take care to update
* multiSlsDetectors thisMultiDetector->numberofDetectors
* and not use this object again (delete and start anew)
* Is only safe to call if one deletes the slsDetector object afterward
* and frees multi shared memory/updates thisMultiDetector->numberOfDetectors
*/
void freeSharedMemory();
/**
* Get user details of shared memory
* Should only be called from multi detector level
* @returns string with user details
*/
std::string getUserDetails();
/**
* Sets the hostname of all sls detectors in shared memory
* Connects to them to set up online flag
@ -495,6 +501,14 @@ public:
*/
string getHostname(int pos = -1);
/**
* Appends detectors to the end of the list in shared memory
* Connects to them to set up online flag
* Should only be called from multi detector level
* @param name concatenated hostname of the sls detectors to be appended to the list
*/
void addMultipleDetectors(const char* name);
/**
* Connect to the control port
* @returns OK, FAIL or undefined

View File

@ -264,19 +264,33 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
++i;
/*! \page config
- \b add Adds a detector at the end of the multi-detector structure. \c put argument is the hostname or IP adress. cannot get. \c Returns the current list of detector hostnames. \c (string)
- <b>hostname</b> \c put frees shared memory and sets the hostname (or IP adress). Only allowed at multi detector level. \c Returns the list of the hostnames of the multi-detector structure. \c (string)
*/
descrToFuncMap[i].m_pFuncName="hostname"; //OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname;
++i;
/*! \page config
- \b add appends a hostname (or IP address) at the end of the multi-detector structure. Only allowed at multi detector level. Cannot get. \c Returns the current list of detector hostnames. \c (string)
*/
descrToFuncMap[i].m_pFuncName="add";//OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname;
++i;
/*! \page config
- <b>hostname</b> \c put frees shared memory and sets the hostname (or IP adress).\c Returns the list of the hostnames of the multi-detector structure. \c Returns \c (string)
- <b>replace</b> \c Sets the hostname (or IP adress) for a single detector. Only allowed at single detector level. Cannot get. \c Returns the hostnames for that detector \c (string)
*/
descrToFuncMap[i].m_pFuncName="hostname"; //OK
descrToFuncMap[i].m_pFuncName="replace"; //OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname;
++i;
/*! \page config
- <b>user</b> \c Returns user details from shared memory. Only allowed at multi detector level. Cannot put. \c (string)
*/
descrToFuncMap[i].m_pFuncName="user"; //OK
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdUser;
++i;
/*! \page config
- <b>master i</b> \c put sets the position of the master of the acquisition (-1 if none). Returns the position of the master of the detector structure (-1 if none).
*/
@ -2686,76 +2700,16 @@ string slsDetectorCommand::cmdFree(int narg, char *args[], int action) {
if (action==HELP_ACTION) {
return helpFree(narg,args,HELP_ACTION);
}
myDet->freeSharedMemory();
return("freed");
return("Error: Should have been freed before creating constructor\n");
}
string slsDetectorCommand::helpFree(int narg, char *args[], int action) {
return string("free \t frees the shared memory\n");
}
/*
string slsDetectorCommand::cmdAdd(int narg, char *args[], int action) {
#ifdef VERBOSE
cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n");
#endif
int ivar, ival;
string var=string(args[0]);
ostringstream os;
if (action==HELP_ACTION) {
return helpAdd(narg,args,HELP_ACTION);
} else if (action==GET_ACTION) {
return string("cannot get");
}else if (myDet->isMultiSlsDetectorClass()) {
return string ("cannot replace detectors from multi detector level.");
}
char hostname[1000];
strcpy(hostname,"");
// if each argument is a hostname
for (int id=1; id<narg; ++id) {
strcat(hostname,args[id]);
if(narg>2)
strcat(hostname,"+");
}
myDet->setHostname(hostname);
return myDet->getHostname();
}
string slsDetectorCommand::helpAdd(int narg, char *args[], int action){
return string("add det [det det]\t appends a detector(s) to the multi detector structure. "
"det can either be the detector hostname or the detector id. "
"Returns hostnames in the multi detector structure\n");
}
string slsDetectorCommand::cmdReplace(int narg, char *args[], int action){
#ifdef VERBOSE
cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n");
#endif
if (action==HELP_ACTION) {
return helpRemove(narg,args,HELP_ACTION);
} else if (action==GET_ACTION) {
return string ("cannot get");
} else if (myDet->isMultiSlsDetectorClass()) {
return string ("cannot replace detectors from multi detector level.");
}
return myDet->replaceDetector(string(argv[1]));
}
string slsDetectorCommand::helpReplace(int narg, char *args[], int action){
return string("rename det \t replaces a detector. "
"det can either be the detector hostname or ip. "
"Returns the total number of "
"detectors in the multidetector structure\n");
}
*/
string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){
#ifdef VERBOSE
cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n");
@ -2764,17 +2718,21 @@ string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){
if (action==HELP_ACTION) {
return helpHostname(narg,args,HELP_ACTION);
}
if ((action==GET_ACTION) && (cmd == "add")) {
return string("cannot get");
if (action==GET_ACTION) {
if ((cmd == "add") || (cmd == "replace"))
return string("cannot get");
}
if (action==PUT_ACTION) {
if (!myDet->isMultiSlsDetectorClass()) {
return string ("Wrong usage - setting hostname only from "
if (((cmd == "add") || (cmd == "hostname")) &&
(!myDet->isMultiSlsDetectorClass())) {
return string ("Wrong usage - setting hostname/add only from "
"multiDetector level");
}
if ((cmd == "replace") && (myDet->isMultiSlsDetectorClass())) {
return string ("Wrong usage - replace only from "
"single detector level");
}
char hostname[1000];
strcpy(hostname,"");
// if each argument is a hostname
@ -2783,31 +2741,73 @@ string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){
if(narg>2)
strcat(hostname,"+");
}
myDet->setHostname(hostname);
if (cmd == "add")
myDet->addMultipleDetectors(hostname);
else
myDet->setHostname(hostname);
}
return string(myDet->getHostname());
return myDet->getHostname();
}
string slsDetectorCommand::helpHostname(int narg, char *args[], int action){
ostringstream os;
if (action==GET_ACTION || action==HELP_ACTION)
os << string("hostname \t returns the hostname(s) of the detector structure.");
if (action==GET_ACTION || action==HELP_ACTION) {
os << string("hostname \t returns the hostname(s) of the multi detector structure.\n");
os << string("add \t cannot get\n");
os << string("replace \t cannot get\n");
}
if (action==PUT_ACTION || action==HELP_ACTION) {
os << string("hostname name [name name]\t frees shared memory and "
"configures the hostnames of the detector structure.\n");
os << string ("add det [det det]\t appends a detector(s) to the multi detector structure. "
"det can either be the detector hostname or the detector id. "
"sets the hostname (or IP adress). Only allowed at multi detector level.\n");
os << string ("add det [det det]\t appends a hostname (or IP address) at "
"the end of the multi-detector structure. Only allowed at multi detector level."
"Returns hostnames in the multi detector structure\n");
os << string ("replace det \t Sets the hostname (or IP adress) for a "
"single detector. Only allowed at single detector level. "
"Returns the hostnames for that detector\n");
}
return os.str();
}
string slsDetectorCommand::cmdUser(int narg, char *args[], int action){
#ifdef VERBOSE
cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n");
#endif
if (action==HELP_ACTION) {
return helpHostname(narg,args,HELP_ACTION);
}
if (action==PUT_ACTION) {
return string("cannot put");
}
if (!myDet->isMultiSlsDetectorClass()) {
return string ("Wrong usage - getting user details only from "
"multiDetector level");
}
return myDet->getUserDetails();
}
string slsDetectorCommand::helpUser(int narg, char *args[], int action){
ostringstream os;
if (action==GET_ACTION || action==HELP_ACTION) {
os << string("user \t returns user details from shared memory without updating shared memory. "
"Only allowed at multi detector level.\n");
}
if (action==PUT_ACTION || action==HELP_ACTION) {
os << string("user \t cannot put\n");
}
return os.str();
}
string slsDetectorCommand::cmdMaster(int narg, char *args[], int action){
#ifdef VERBOSE
cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n");

View File

@ -40,9 +40,8 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
static std::string helpStatus(int narg, char *args[], int action);
static std::string helpDataStream(int narg, char *args[], int action);
static std::string helpFree(int narg, char *args[], int action);
// static std::string helpAdd(int narg, char *args[], int action);
// static std::string helpReplace(int narg, char *args[], int action);
static std::string helpHostname(int narg, char *args[], int action);
static std::string helpUser(int narg, char *args[], int action);
static std::string helpMaster(int narg, char *args[], int action);
static std::string helpSync(int narg, char *args[], int action);
static std::string helpExitServer(int narg, char *args[], int action);
@ -112,9 +111,8 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
std::string cmdStatus(int narg, char *args[], int action);
std::string cmdDataStream(int narg, char *args[], int action);
std::string cmdFree(int narg, char *args[], int action);
//std::string cmdAdd(int narg, char *args[], int action);
//std::string cmdReplace(int narg, char *args[], int action);
std::string cmdHostname(int narg, char *args[], int action);
std::string cmdUser(int narg, char *args[], int action);
std::string cmdMaster(int narg, char *args[], int action);
std::string cmdSync(int narg, char *args[], int action);
std::string cmdHelp(int narg, char *args[], int action);
@ -171,7 +169,6 @@ class slsDetectorCommand : public virtual slsDetectorDefs {
struct FuncTable
{
std::string m_pFuncName;
//const char* m_pFuncName;
MemFuncGetter m_pFuncPtr;
};

View File

@ -207,6 +207,10 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
*/
virtual void setHostname(const char* name)=0;
/** adds the detector hostnames to the end of the list
\param name hostname
*/
virtual void addMultipleDetectors(const char* name)=0;
/** returns the detector type
\param pos position in the multi detector structure (is -1 returns type of detector with id -1)
@ -396,14 +400,11 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
/** Frees the shared memory - should not be used except for debugging*/
virtual void freeSharedMemory()=0;
/** adds the detector with ID id in postion pos
\param id of the detector to be added (should already exist!)
\param pos position where it should be added (normally at the end of the list (default to -1)
\returns the actual number of detectors or -1 if it failed (always for slsDetector)
*/
virtual int addSlsDetector(int id, int pos=-1){return -1;};
/**
* Get user details of shared memory
* @returns string with user details
*/
virtual std::string getUserDetails() = 0;
/** adds the detector name in position pos
\param name of the detector to be added (should already exist in shared memory or at least be online)
@ -413,19 +414,6 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
virtual int addSlsDetector(char* name, int pos=-1){return -1;};
/**
removes the detector in position pos from the multidetector
\param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector)
\returns the actual number of detectors or -1 if it failed (always for slsDetector)
*/
virtual int removeSlsDetector(int pos=-1){return -1;};
/**removes the detector in position pos from the multidetector
\param name is the name of the detector
\returns the actual number of detectors or -1 if it failed (always for slsDetector)
*/
virtual int removeSlsDetector(char* name){return -1;};
/**
Turns off the server - do not use except for debugging!
*/