Improvements/tests for SEM_LIVE locking
This commit is contained in:
parent
3aeebd1a4a
commit
bafe30e234
5 changed files with 53 additions and 28 deletions
|
@ -46,7 +46,7 @@ namespace IPC {
|
||||||
#else
|
#else
|
||||||
mySem = SEM_FAILED;
|
mySem = SEM_FAILED;
|
||||||
#endif
|
#endif
|
||||||
isLocked = false;
|
isLocked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Constructs a named semaphore
|
///\brief Constructs a named semaphore
|
||||||
|
@ -60,7 +60,7 @@ namespace IPC {
|
||||||
#else
|
#else
|
||||||
mySem = SEM_FAILED;
|
mySem = SEM_FAILED;
|
||||||
#endif
|
#endif
|
||||||
isLocked = false;
|
isLocked = 0;
|
||||||
open(name, oflag, mode, value, noWait);
|
open(name, oflag, mode, value, noWait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,13 +167,18 @@ namespace IPC {
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (*this) {
|
|
||||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||||
ReleaseMutex(mySem);
|
ReleaseMutex(mySem);
|
||||||
#else
|
#else
|
||||||
sem_post(mySem);
|
sem_post(mySem);
|
||||||
#endif
|
#endif
|
||||||
isLocked = false;
|
--isLocked;
|
||||||
|
if (!isLocked){
|
||||||
|
uint64_t micros = Util::getMicros(lockTime);
|
||||||
|
if (micros > 500){
|
||||||
|
INFO_MSG("Semaphore %s was locked for %.3f ms", myName.c_str(), (double)micros/1000.0);
|
||||||
|
BACKTRACE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +193,8 @@ namespace IPC {
|
||||||
tmp = sem_wait(mySem);
|
tmp = sem_wait(mySem);
|
||||||
} while (tmp == -1 && errno == EINTR);
|
} while (tmp == -1 && errno == EINTR);
|
||||||
#endif
|
#endif
|
||||||
isLocked = true;
|
lockTime = Util::getMicros();
|
||||||
|
++isLocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +213,9 @@ namespace IPC {
|
||||||
result = sem_trywait(mySem);
|
result = sem_trywait(mySem);
|
||||||
} while (result == -1 && errno == EINTR);
|
} while (result == -1 && errno == EINTR);
|
||||||
#endif
|
#endif
|
||||||
return isLocked = (result == 0);
|
isLocked += (result == 0?1:0);
|
||||||
|
if (isLocked == 1){lockTime = Util::getMicros();}
|
||||||
|
return isLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Tries to wait for the semaphore for a single second, returns true if successful, false otherwise
|
///\brief Tries to wait for the semaphore for a single second, returns true if successful, false otherwise
|
||||||
|
@ -224,28 +232,27 @@ namespace IPC {
|
||||||
/// \todo (roxlu) test tryWaitOneSecond, shared_memory.cpp
|
/// \todo (roxlu) test tryWaitOneSecond, shared_memory.cpp
|
||||||
uint64_t now = Util::getMicros();
|
uint64_t now = Util::getMicros();
|
||||||
uint64_t timeout = now + 1e6;
|
uint64_t timeout = now + 1e6;
|
||||||
while (now < timeout) {
|
result = 1;
|
||||||
if (0 == sem_trywait(mySem)) {
|
while (result && now < timeout) {
|
||||||
isLocked = true;
|
result = sem_trywait(mySem);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
usleep(100e3);
|
usleep(100e3);
|
||||||
now = Util::getMicros();
|
now = Util::getMicros();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
#else
|
#else
|
||||||
struct timespec wt;
|
struct timespec wt;
|
||||||
wt.tv_sec = 1;
|
wt.tv_sec = 1;
|
||||||
wt.tv_nsec = 0;
|
wt.tv_nsec = 0;
|
||||||
result = sem_timedwait(mySem, &wt);
|
result = sem_timedwait(mySem, &wt);
|
||||||
#endif
|
#endif
|
||||||
return isLocked = (result == 0);
|
isLocked += (result == 0?1:0);
|
||||||
|
if (isLocked == 1){lockTime = Util::getMicros();}
|
||||||
|
return isLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
///\brief Closes the currently opened semaphore
|
///\brief Closes the currently opened semaphore
|
||||||
void semaphore::close() {
|
void semaphore::close() {
|
||||||
if (*this) {
|
if (*this) {
|
||||||
if (isLocked){post();}
|
while (isLocked){post();}
|
||||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||||
CloseHandle(mySem);
|
CloseHandle(mySem);
|
||||||
mySem = 0;
|
mySem = 0;
|
||||||
|
@ -275,7 +282,7 @@ namespace IPC {
|
||||||
/// Unlinks the previously opened semaphore, closing it (if open) in the process.
|
/// Unlinks the previously opened semaphore, closing it (if open) in the process.
|
||||||
void semaphore::unlink() {
|
void semaphore::unlink() {
|
||||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||||
if (isLocked){post();}
|
while (isLocked){post();}
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
#if !defined(__CYGWIN__) && !defined(_WIN32)
|
||||||
if (myName.size()){sem_unlink(myName.c_str());}
|
if (myName.size()){sem_unlink(myName.c_str());}
|
||||||
|
|
|
@ -85,7 +85,8 @@ namespace IPC {
|
||||||
#else
|
#else
|
||||||
sem_t * mySem;
|
sem_t * mySem;
|
||||||
#endif
|
#endif
|
||||||
bool isLocked;
|
unsigned int isLocked;
|
||||||
|
uint64_t lockTime;
|
||||||
std::string myName;
|
std::string myName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -931,7 +931,7 @@ void Controller::fillActive(JSON::Value & req, JSON::Value & rep, bool onlyNow){
|
||||||
if (streamIndex.mapped){
|
if (streamIndex.mapped){
|
||||||
static char liveSemName[NAME_BUFFER_SIZE];
|
static char liveSemName[NAME_BUFFER_SIZE];
|
||||||
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, it->c_str());
|
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, it->c_str());
|
||||||
IPC::semaphore metaLocker(liveSemName, O_CREAT | O_RDWR, (S_IRWXU|S_IRWXG|S_IRWXO), 1);
|
IPC::semaphore metaLocker(liveSemName, O_CREAT | O_RDWR, (S_IRWXU|S_IRWXG|S_IRWXO), 8);
|
||||||
metaLocker.wait();
|
metaLocker.wait();
|
||||||
DTSC::Scan strm = DTSC::Packet(streamIndex.mapped, streamIndex.len, true).getScan();
|
DTSC::Scan strm = DTSC::Packet(streamIndex.mapped, streamIndex.len, true).getScan();
|
||||||
uint64_t lms = 0;
|
uint64_t lms = 0;
|
||||||
|
|
|
@ -195,9 +195,16 @@ namespace Mist {
|
||||||
if (!liveMeta){
|
if (!liveMeta){
|
||||||
static char liveSemName[NAME_BUFFER_SIZE];
|
static char liveSemName[NAME_BUFFER_SIZE];
|
||||||
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
||||||
liveMeta = new IPC::semaphore(liveSemName, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
liveMeta = new IPC::semaphore(liveSemName, O_CREAT | O_RDWR, ACCESSPERMS, 8);
|
||||||
}
|
}
|
||||||
liveMeta->wait();
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
liveMeta->wait();
|
||||||
|
|
||||||
if (!nProxy.metaPages.count(0) || !nProxy.metaPages[0].mapped) {
|
if (!nProxy.metaPages.count(0) || !nProxy.metaPages[0].mapped) {
|
||||||
char pageName[NAME_BUFFER_SIZE];
|
char pageName[NAME_BUFFER_SIZE];
|
||||||
|
@ -208,6 +215,13 @@ namespace Mist {
|
||||||
myMeta.writeTo(nProxy.metaPages[0].mapped);
|
myMeta.writeTo(nProxy.metaPages[0].mapped);
|
||||||
memset(nProxy.metaPages[0].mapped + myMeta.getSendLen(), 0, (nProxy.metaPages[0].len > myMeta.getSendLen() ? std::min((size_t)(nProxy.metaPages[0].len - myMeta.getSendLen()), (size_t)4) : 0));
|
memset(nProxy.metaPages[0].mapped + myMeta.getSendLen(), 0, (nProxy.metaPages[0].len > myMeta.getSendLen() ? std::min((size_t)(nProxy.metaPages[0].len - myMeta.getSendLen()), (size_t)4) : 0));
|
||||||
liveMeta->post();
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
|
liveMeta->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
///Checks if removing a key from this track is allowed/safe, and if so, removes it.
|
///Checks if removing a key from this track is allowed/safe, and if so, removes it.
|
||||||
|
@ -515,12 +529,12 @@ namespace Mist {
|
||||||
updateTrackMeta(finalMap);
|
updateTrackMeta(finalMap);
|
||||||
hasPush = true;
|
hasPush = true;
|
||||||
}
|
}
|
||||||
|
//Update the metadata to reflect all changes
|
||||||
|
updateMeta();
|
||||||
//Write the final mapped track number and keyframe number to the user page element
|
//Write the final mapped track number and keyframe number to the user page element
|
||||||
//This is used to resume pushing as well as pushing new tracks
|
//This is used to resume pushing as well as pushing new tracks
|
||||||
userConn.setTrackId(index, finalMap);
|
userConn.setTrackId(index, finalMap);
|
||||||
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.size());
|
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.size());
|
||||||
//Update the metadata to reflect all changes
|
|
||||||
updateMeta();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Set the temporary track id for this item, and increase the temporary value for use with the next track
|
//Set the temporary track id for this item, and increase the temporary value for use with the next track
|
||||||
|
@ -643,12 +657,16 @@ namespace Mist {
|
||||||
myMeta.tracks[finalMap].lastms = 0;
|
myMeta.tracks[finalMap].lastms = 0;
|
||||||
myMeta.tracks[finalMap].trackID = finalMap;
|
myMeta.tracks[finalMap].trackID = finalMap;
|
||||||
}
|
}
|
||||||
|
//Update the metadata to reflect all changes
|
||||||
|
updateMeta();
|
||||||
//Write the final mapped track number and keyframe number to the user page element
|
//Write the final mapped track number and keyframe number to the user page element
|
||||||
//This is used to resume pushing as well as pushing new tracks
|
//This is used to resume pushing as well as pushing new tracks
|
||||||
userConn.setTrackId(index, finalMap);
|
userConn.setTrackId(index, finalMap);
|
||||||
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.size());
|
if (myMeta.tracks[finalMap].keys.size()){
|
||||||
//Update the metadata to reflect all changes
|
userConn.setKeynum(index, myMeta.tracks[finalMap].keys.rbegin()->getNumber());
|
||||||
updateMeta();
|
}else{
|
||||||
|
userConn.setKeynum(index, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//If the track is active, and this is the element responsible for pushing it
|
//If the track is active, and this is the element responsible for pushing it
|
||||||
if (activeTracks.count(value) && pushLocation[value] == data) {
|
if (activeTracks.count(value) && pushLocation[value] == data) {
|
||||||
|
@ -694,7 +712,6 @@ namespace Mist {
|
||||||
for (std::map<unsigned long, DTSCPageData>::iterator pageIt = locations.begin(); pageIt != locations.end(); pageIt++) {
|
for (std::map<unsigned long, DTSCPageData>::iterator pageIt = locations.begin(); pageIt != locations.end(); pageIt++) {
|
||||||
updateMetaFromPage(tNum, pageIt->first);
|
updateMetaFromPage(tNum, pageIt->first);
|
||||||
}
|
}
|
||||||
updateMeta();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputBuffer::updateMetaFromPage(unsigned long tNum, unsigned long pageNum) {
|
void inputBuffer::updateMetaFromPage(unsigned long tNum, unsigned long pageNum) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ namespace Mist{
|
||||||
if (!myMeta.vod){
|
if (!myMeta.vod){
|
||||||
static char liveSemName[NAME_BUFFER_SIZE];
|
static char liveSemName[NAME_BUFFER_SIZE];
|
||||||
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
||||||
liveSem = new IPC::semaphore(liveSemName, O_RDWR, ACCESSPERMS, 1, !myMeta.live);
|
liveSem = new IPC::semaphore(liveSemName, O_RDWR, ACCESSPERMS, 8, !myMeta.live);
|
||||||
if (*liveSem){
|
if (*liveSem){
|
||||||
liveSem->wait();
|
liveSem->wait();
|
||||||
}else{
|
}else{
|
||||||
|
@ -1411,7 +1411,7 @@ namespace Mist{
|
||||||
IPC::semaphore * liveSem = 0;
|
IPC::semaphore * liveSem = 0;
|
||||||
static char liveSemName[NAME_BUFFER_SIZE];
|
static char liveSemName[NAME_BUFFER_SIZE];
|
||||||
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
|
||||||
liveSem = new IPC::semaphore(liveSemName, O_RDWR, ACCESSPERMS, 1, !myMeta.live);
|
liveSem = new IPC::semaphore(liveSemName, O_RDWR, ACCESSPERMS, 8, !myMeta.live);
|
||||||
if (*liveSem){
|
if (*liveSem){
|
||||||
liveSem->wait();
|
liveSem->wait();
|
||||||
}else{
|
}else{
|
||||||
|
|
Loading…
Add table
Reference in a new issue