Cleaned up, fixed and robustified semaphore and signal related code

This commit is contained in:
Thulinma 2018-11-01 16:11:47 +01:00
parent ee9b076b76
commit 24006648f9
7 changed files with 165 additions and 131 deletions

View file

@ -401,7 +401,7 @@ void Util::Config::activate() {
struct sigaction cur_action;
new_action.sa_sigaction = signal_handler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
new_action.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &new_action, NULL);
sigaction(SIGHUP, &new_action, NULL);
sigaction(SIGTERM, &new_action, NULL);
@ -423,6 +423,10 @@ void Util::Config::signal_handler(int signum, siginfo_t * sigInfo, void * ignore
case SIGHUP:
case SIGTERM:
if (serv_sock_pointer){serv_sock_pointer->close();}
#if DEBUG >= DLVL_DEVEL
static int ctr = 0;
if (!is_active && ++ctr > 4){BACKTRACE;}
#endif
is_active = false;
default:
switch (sigInfo->si_code){

View file

@ -93,6 +93,7 @@ namespace IPC {
#else
mySem = SEM_FAILED;
#endif
isLocked = false;
}
///\brief Constructs a named semaphore
@ -106,6 +107,7 @@ namespace IPC {
#else
mySem = SEM_FAILED;
#endif
isLocked = false;
open(name, oflag, mode, value, noWait);
}
@ -178,9 +180,9 @@ namespace IPC {
}
#endif
}
if (!(*this)) {
if (*this) {
myName = (char *)name;
}
myName = (char *)name;
}
///\brief Returns the current value of the semaphore
@ -197,12 +199,20 @@ namespace IPC {
///\brief Posts to the semaphore, increases its value by one
void semaphore::post() {
if (!*this || !isLocked){
FAIL_MSG("Attempted to unlock a non-locked semaphore: '%s'!", myName.c_str());
#if DEBUG >= DLVL_DEVEL
BACKTRACE;
#endif
return;
}
if (*this) {
#if defined(__CYGWIN__) || defined(_WIN32)
ReleaseMutex(mySem);
#else
sem_post(mySem);
#endif
isLocked = false;
}
}
@ -217,6 +227,7 @@ namespace IPC {
tmp = sem_wait(mySem);
} while (tmp == -1 && errno == EINTR);
#endif
isLocked = true;
}
}
@ -235,7 +246,7 @@ namespace IPC {
result = sem_trywait(mySem);
} while (result == -1 && errno == EINTR);
#endif
return (result == 0);
return isLocked = (result == 0);
}
///\brief Tries to wait for the semaphore for a single second, returns true if successful, false otherwise
@ -254,6 +265,7 @@ namespace IPC {
long long unsigned int timeout = now + 1e6;
while (now < timeout) {
if (0 == sem_trywait(mySem)) {
isLocked = true;
return true;
}
usleep(100e3);
@ -266,12 +278,28 @@ namespace IPC {
wt.tv_nsec = 0;
result = sem_timedwait(mySem, &wt);
#endif
return (result == 0);
return isLocked = (result == 0);
}
///\brief Closes the currently opened semaphore
void semaphore::close() {
if (*this) {
if (isLocked){post();}
#if defined(__CYGWIN__) || defined(_WIN32)
CloseHandle(mySem);
mySem = 0;
#else
sem_close(mySem);
mySem = SEM_FAILED;
#endif
}
myName.clear();
}
/// Closes the semaphore, without unlocking it first.
/// Intended to be called from forked child processes, to drop the reference to the semaphore.
void semaphore::abandon() {
if (*this) {
#if defined(__CYGWIN__) || defined(_WIN32)
CloseHandle(mySem);
mySem = 0;
@ -280,19 +308,28 @@ namespace IPC {
mySem = SEM_FAILED;
#endif
}
}
///\brief Unlinks the previously opened semaphore
void semaphore::unlink() {
close();
#if !defined(__CYGWIN__) && !defined(_WIN32)
if (myName.size()) {
sem_unlink(myName.c_str());
}
#endif
myName.clear();
}
/// Unlinks the previously opened semaphore, closing it (if open) in the process.
void semaphore::unlink() {
#if defined(__CYGWIN__) || defined(_WIN32)
if (isLocked){post();}
#endif
#if !defined(__CYGWIN__) && !defined(_WIN32)
if (myName.size()){sem_unlink(myName.c_str());}
#endif
if (*this) {
#if defined(__CYGWIN__) || defined(_WIN32)
CloseHandle(mySem);
mySem = 0;
#else
sem_close(mySem);
mySem = SEM_FAILED;
#endif
}
myName.clear();
}
#if defined(__CYGWIN__) || defined(_WIN32)
SECURITY_ATTRIBUTES semaphore::getSecurityAttributes() {
@ -368,7 +405,7 @@ namespace IPC {
///\brief Unmaps a shared page if allowed
void sharedPage::unmap() {
if (mapped && len) {
if (mapped) {
#if defined(__CYGWIN__) || defined(_WIN32)
//under Cygwin, the mapped location is shifted by 4 to contain the page size.
UnmapViewOfFile(mapped - 4);
@ -795,26 +832,19 @@ namespace IPC {
baseName = "/" + name;
payLen = len;
hasCounter = withCounter;
mySemaphore.open(baseName.c_str(), O_CREAT | O_EXCL | O_RDWR, ACCESSPERMS, 1);
if (!mySemaphore) {
mySemaphore.open(baseName.c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1);
}
mySemaphore.open(baseName.c_str(), O_CREAT | O_RDWR, ACCESSPERMS, 1);
if (!mySemaphore) {
DEBUG_MSG(DLVL_FAIL, "Creating semaphore failed: %s", strerror(errno));
return;
}else{
semGuard tmpGuard(&mySemaphore);
amount = 0;
newPage();
}
if (!mySemaphore.tryWaitOneSecond()){
WARN_MSG("Force unlocking sharedServer semaphore to prevent deadlock");
}
mySemaphore.post();
semGuard tmpGuard(&mySemaphore);
amount = 0;
newPage();
}
///\brief The deconstructor
sharedServer::~sharedServer() {
mySemaphore.close();
mySemaphore.unlink();
}
@ -1251,7 +1281,7 @@ namespace IPC {
if (!hasCounter) {
return (myPage.mapped != 0);
}
if (myPage.mapped){
if (myPage.mapped && offsetOnPage >= 0){
return (myPage.mapped[offsetOnPage] & 0x7F) < 60;
}
return false;

View file

@ -75,6 +75,7 @@ namespace IPC {
bool tryWait();
bool tryWaitOneSecond();
void close();
void abandon();
void unlink();
private:
#if defined(__CYGWIN__) || defined(_WIN32)
@ -84,6 +85,7 @@ namespace IPC {
#else
sem_t * mySem;
#endif
bool isLocked;
std::string myName;
};