1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
2023-04-21 13:23:58 +00:00

154 lines
4.0 KiB
C++

/* Copyright (C) 2014 InfiniDB, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/*
* rwlockmonitor.cpp
*
* Created on: Aug 15, 2011
* Author: pleblanc
*/
#include <unistd.h>
#include <iostream>
#define RWLOCKMONITOR_DLLEXPORT
#include "rwlockmonitor.h"
#undef RWLOCKMONITOR_DLLEXPORT
#include "logger.h"
#include "errorids.h"
using namespace std;
using namespace rwlock;
using namespace logging;
namespace BRM
{
RWLockMonitor::RWLockMonitor(const std::atomic<bool>* d, const std::atomic<bool>* ls, const uint32_t k) : die(d), lockStatus(ls), key(k)
{
ts.tv_sec = 210; // 3:30 timer
ts.tv_nsec = 0;
secsBetweenAttempts = 30;
lock.reset(new RWLock(key));
}
RWLockMonitor::~RWLockMonitor()
{
}
void RWLockMonitor::operator()()
{
/*
* Grab a timed write lock.
* on failure
* if there's an active reader, do read_unlock()
* log everything else.
* *** write lock fixing is being postponed for now.
*/
LockState state;
bool gotTheLock;
bool reportedProblem = false;
Logger logger(30);
while (!(*die))
{
gotTheLock = lock->timed_write_lock(ts, &state);
if (*die)
break;
if (!gotTheLock)
{
if (state.mutexLocked)
{
if (!reportedProblem)
{
// Message msg(ERR_BRM_MUTEX);
Message msg(M0092);
logger.logMessage(LOG_TYPE_CRITICAL, msg, LoggingID());
reportedProblem = true;
}
}
else if (state.reading > 0)
{
if (!reportedProblem)
{
// Message msg(ERR_RECOVERABLE_LOCK_STATE);
Message msg(M0094);
Message::Args args;
args.add(state.reading);
args.add(state.readerswaiting);
args.add(state.writing);
args.add(state.writerswaiting);
msg.format(args);
logger.logMessage(LOG_TYPE_WARNING, msg, LoggingID());
reportedProblem = true;
}
for (int i = 0; i < state.reading; i++)
lock->read_unlock();
}
// the write lock is held but not by this process, not good.
// there's a slight race here between these two vars but it's miniscule,
// and the worst thing that happens is a false positive error msg.
else if (state.writing > 0 && !(*lockStatus))
{
if (!reportedProblem)
{
// Message msg(ERR_UNRECOVERABLE_LOCK_STATE);
Message msg(M0093);
Message::Args args;
args.add(state.reading);
args.add(state.readerswaiting);
args.add(state.writing);
args.add(state.writerswaiting);
msg.format(args);
logger.logMessage(LOG_TYPE_CRITICAL, msg, LoggingID());
reportedProblem = true;
}
/* put write lock recovery code here */
}
else
{
// the workernode is legitmately taking a long time
// cout << "holds the lock. " << " r=" << state.reading << " rwt=" << state.readerswaiting <<
// " w=" << state.writing << " wwt=" << state.writerswaiting << endl;
}
}
else
{
/* got the write lock. If there was a problem before it's been fixed. */
lock->write_unlock();
if (reportedProblem)
{
// Message msg(ERR_SUCCESSFUL_RECOVERY);
Message msg(M0095);
logger.logMessage(LOG_TYPE_WARNING, msg, LoggingID());
reportedProblem = false;
}
sleep(secsBetweenAttempts);
}
}
}
} /* namespace BRM */