Commit 3d4d90ab authored by Steven Murray's avatar Steven Murray
Browse files

Removed unused cpp files from the tapeserver/castor/server directory

parent ded127d7
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2004 CERN
* 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; either version 2
* of the License, or (at your option) any later version.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* C++ interface to mutex handling with the Cthread API
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
// Include Files
#include <signal.h>
#include "castor/server/AllInOneLockingUtility.hpp"
#include "Cthread_api.h"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::server::AllInOneLockingUtility::AllInOneLockingUtility(int value, unsigned int timeout)
:
m_var(value), m_timeout(timeout), m_mutexCthread(0)
{
if(createLock() != 0) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to create mutex";
throw ex;
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::server::AllInOneLockingUtility::~AllInOneLockingUtility()
{
Cthread_mutex_unlock_ext(m_mutexCthread);
// Cthread_mutex_destroy(m_mutexCthread); // XXX this causes a deadlock!
// XXX to be eventually replaced by standard pthread mutexes
}
//------------------------------------------------------------------------------
// createLock
//------------------------------------------------------------------------------
int castor::server::AllInOneLockingUtility::createLock()
{
if(Cthread_mutex_timedlock(&m_var, m_timeout) != 0) {
return -1;
}
m_mutexCthread = Cthread_mutex_lock_addr(&m_var);
if(m_mutexCthread == 0) {
Cthread_mutex_unlock(&m_var);
return -1;
}
if(Cthread_mutex_unlock_ext(m_mutexCthread) != 0) {
return -1;
}
return 0;
}
//------------------------------------------------------------------------------
// setValue
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::setValue(int newValue)
{
int oldValue = m_var;
lock();
m_var = newValue;
try {
release();
} catch(castor::exception::Exception& e) {
m_var = oldValue;
throw e;
}
}
//------------------------------------------------------------------------------
// setValueNoEx
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::setValueNoEx(int newValue)
{
if (Cthread_mutex_timedlock_ext(m_mutexCthread, m_timeout) == 0) {
m_var = newValue;
Cthread_mutex_unlock_ext(m_mutexCthread);
}
else { // thread-unsafe
m_var = newValue;
}
}
//------------------------------------------------------------------------------
// wait
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::wait()
{
if (m_mutexCthread == 0)
return;
Cthread_cond_timedwait_ext(m_mutexCthread, m_timeout);
// here the timeout was previously defined as COND_TIMEOUT, by default = TIMEOUT
}
//------------------------------------------------------------------------------
// lock
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::lock()
{
if (m_mutexCthread == 0 ||
Cthread_mutex_timedlock_ext(m_mutexCthread, m_timeout) != 0) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to lock mutex";
throw ex;
}
}
//------------------------------------------------------------------------------
// release
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::release()
{
if(Cthread_mutex_unlock_ext(m_mutexCthread) != 0) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to release mutex";
throw ex;
}
}
//------------------------------------------------------------------------------
// signal
//------------------------------------------------------------------------------
void castor::server::AllInOneLockingUtility::signal()
{
if (m_mutexCthread == 0 ||
Cthread_cond_signal_ext(m_mutexCthread) != 0) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to signal mutex";
throw ex;
}
}
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2004 CERN
* 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; either version 2
* of the License, or (at your option) any later version.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* A ListenerThreadPool which uses AuthSockets to handle the connections
*
* @author Castor Dev team, castor-dev@cern.ch
******************************************************** *********************/
// Include Files
#include <signal.h>
#include "castor/io/AuthServerSocket.hpp"
#include "castor/server/AuthListenerThreadPool.hpp"
#include "castor/exception/Exception.hpp"
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
castor::server::AuthListenerThreadPool::AuthListenerThreadPool
(const std::string poolName,
castor::server::IThread* thread,
unsigned int listenPort,
bool waitIfBusy,
unsigned int nbThreads) :
TCPListenerThreadPool(poolName, thread, listenPort, waitIfBusy, nbThreads) {}
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
castor::server::AuthListenerThreadPool::AuthListenerThreadPool
(const std::string poolName,
castor::server::IThread* thread,
unsigned int listenPort,
bool waitIfBusy,
unsigned int initThreads,
unsigned int maxThreads,
unsigned int threshold,
unsigned int maxTasks) :
TCPListenerThreadPool(poolName, thread, listenPort, waitIfBusy,
initThreads, maxThreads, threshold, maxTasks) {}
//------------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------------
castor::server::AuthListenerThreadPool::~AuthListenerThreadPool() throw() {}
//------------------------------------------------------------------------------
// bind
//------------------------------------------------------------------------------
void castor::server::AuthListenerThreadPool::bind()
{
// Create a secure socket for the server, bind, and listen
m_sock = new castor::io::AuthServerSocket(m_port, true);
}
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2004 CERN
* 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; either version 2
* of the License, or (at your option) any later version.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* Abstract CASTOR thread pool
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/server/BaseThreadPool.hpp"
#include "castor/server/metrics/MetricsCollector.hpp"
#include "castor/server/metrics/InternalCounter.hpp"
#include "castor/Services.hpp"
#include "Cinit.h"
#include "Cuuid.h"
#include "serrno.h"
#include <signal.h>
#include <sstream>
#include <iomanip>
#include <errno.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::server::BaseThreadPool::BaseThreadPool(const std::string poolName,
castor::server::IThread* thread,
unsigned int nbThreads)
:
BaseObject(),
m_nbThreads(nbThreads),
m_poolName(poolName),
m_thread(thread),
m_stopped(false),
m_nbActiveThreads(0),
m_idleTime(0),
m_activeTime(0),
m_runsCount(0)
{
if (m_thread == 0) {
castor::exception::Exception e(EINVAL);
e.getMessage() << "A valid thread must be specified";
throw e;
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::server::BaseThreadPool::~BaseThreadPool() throw()
{
shutdown();
delete m_thread;
}
//------------------------------------------------------------------------------
// init
//------------------------------------------------------------------------------
void castor::server::BaseThreadPool::init()
{
// Enable internal monitoring if the metrics collector has already
// been instantiated by the user application
metrics::MetricsCollector* mc = metrics::MetricsCollector::getInstance();
if(mc) {
mc->getHistogram("AvgTaskTime")->addCounter(
new metrics::InternalCounter(*this, "ms",
&castor::server::BaseThreadPool::getAvgTaskTime));
mc->getHistogram("ActivityFactor")->addCounter(
new metrics::InternalCounter(*this, "%",
&castor::server::BaseThreadPool::getActivityFactor));
mc->getHistogram("LoadFactor")->addCounter(
new metrics::InternalCounter(*this, "%",
&castor::server::BaseThreadPool::getLoadFactor));
}
}
//------------------------------------------------------------------------------
// run
//------------------------------------------------------------------------------
void castor::server::BaseThreadPool::run()
{
castor::exception::Exception notImpl;
notImpl.getMessage() <<
"BaseThreadPool is (pseudo)abstract, you must use its derived classes";
throw notImpl;
}
//------------------------------------------------------------------------------
// shutdown
//------------------------------------------------------------------------------
bool castor::server::BaseThreadPool::shutdown(bool) throw()
{
// Children of this class implement a proper shutdown mechanism,
// here we just return.
return true;
}
//------------------------------------------------------------------------------
// setNbThreads
//------------------------------------------------------------------------------
void castor::server::BaseThreadPool::setNbThreads(unsigned int value)
{
m_nbThreads = value;
}
//------------------------------------------------------------------------------
// resetMetrics
//------------------------------------------------------------------------------
void castor::server::BaseThreadPool::resetMetrics()
{
/*
Reset internal counters. Note we're not taking a lock on the mutex to not
slow down the pool's mainstream activity: the consequence is only a less
accurate accounting if a thread is modifying those values at the same time.
Anyway, the metrics collector thread won't risk to run into a div-by-zero
exception as it calls resetMetrics() *after* having collected all metrics.
*/
m_activeTime = 0;
m_idleTime = 0;
m_runsCount = 0;
}
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* 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; either version 2
* of the License, or (at your option) any later version.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "ChildProcess.hpp"
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
void castor::server::ChildProcess::start(Cleanup & cleanup) {
m_pid = fork();
if (!m_pid) {
/* We are the child process. Do our stuff and exit. */
cleanup();
exit(run());
} else if (-1 == m_pid) {
/* We are in the parent process, for failed */
throw castor::exception::Errnum("Failed to fork a child process in castor::server::ChildProcess::ChildProcess()");
}
/* In parent process, child is OK. */
m_started = true;
}
void castor::server::ChildProcess::parseStatus(int status) {
if (WIFEXITED(status)) {
m_finished = true;
m_exited = true;
m_exitCode = WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
m_finished = true;
m_wasKilled = true;
}
}
bool castor::server::ChildProcess::running() {
/* Checking for a running process before starting gets an exception */
if (!m_started) throw ProcessNeverStarted();
/* If we are not aware of process exiting, let's check and collect exit code */
if (!m_finished) {
/* Re-check the status now. */
int status, ret;
castor::exception::Errnum::throwOnMinusOne(
ret = waitpid(m_pid, &status, WNOHANG),
"Error from waitpid in castor::server::ChildProcess::running()");
if (ret == m_pid) parseStatus(status);
}
return !m_finished;
}
void castor::server::ChildProcess::wait() {
/* Checking for a running process before starting gets an exception */
if (!m_started) throw ProcessNeverStarted();
if (m_finished) return;
int status, ret;
castor::exception::Errnum::throwOnMinusOne(
ret = waitpid(m_pid, &status, 0),
"Error from waitpid in castor::server::ChildProcess::wait()");
/* Check child status*/
if (ret == m_pid) parseStatus(status);
if(!m_finished)
throw castor::exception::Exception("Process did not exit after waitpid().");
}
int castor::server::ChildProcess::exitCode() {
if (!m_started) throw ProcessNeverStarted();
if (!m_finished) {
int status, ret;
castor::exception::Errnum::throwOnMinusOne(
ret = waitpid(m_pid, &status, WNOHANG),
"Error from waitpid in castor::server::ChildProcess::running()");
if (ret == m_pid) parseStatus(status);
}
/* Check child status*/
if (!m_finished) {
throw ProcessStillRunning();
}
if (!m_exited) {
throw ProcessWasKilled();
}
return m_exitCode;
}
void castor::server::ChildProcess::kill() {
if (!m_started) throw ProcessNeverStarted();
::kill(m_pid, SIGTERM);
}
/*******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* 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; either version 2
* of the License, or (at your option) any later version.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @author Castor Dev team, castor-dev@cern.ch
******************************************************************************/
#include "castor/dlf/Dlf.hpp"
#include "castor/exception/Errnum.hpp"
#include "castor/io/UDPSocket.hpp"
#include "castor/server/Daemon.hpp"
#include "castor/server/ThreadNotification.hpp"
#include "castor/System.hpp"
#include "Cgetopt.h"
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::server::Daemon::Daemon(std::ostream &stdOut, std::ostream &stdErr,
log::Logger &log) throw():
m_stdOut(stdOut),
m_stdErr(stdErr),
m_log(log),
m_foreground(false),
m_commandLineHasBeenParsed(false) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::server::Daemon::~Daemon() throw() {
}
//------------------------------------------------------------------------------
// parseCommandLine
//------------------------------------------------------------------------------
void castor::server::Daemon::parseCommandLine(int argc,
char *argv[]) {
Coptions_t longopts[4];
longopts[0].name = "foreground";
longopts[0].has_arg = NO_ARGUMENT;
longopts[0].flag = NULL;
longopts[0].val = 'f';
longopts[1].name = "config";
longopts[1].has_arg = REQUIRED_ARGUMENT;
longopts[1].flag = NULL;
longopts[1].val = 'c';
longopts[2].name = "help";
longopts[2].has_arg = NO_ARGUMENT;
longopts[2].flag = NULL;
longopts[2].val = 'h';
longopts[3].name = 0;
Coptind = 1;
Copterr = 0;
Coptreset = 1;
char c;
while ((c = Cgetopt_long(argc, argv, "fc:h", longopts, NULL)) != -1) {
switch (c) {
case 'f':
m_foreground = true;
break;
case 'c':
setenv("PATH_CONFIG", Coptarg, 1);
m_stdOut << "Using configuration file " << Coptarg << std::endl;
break;
case 'h':
help(argv[0]);
exit(0);
break;
default:
break;
}
}
m_commandLineHasBeenParsed = true;
}
//------------------------------------------------------------------------------
// help
//------------------------------------------------------------------------------
void castor::server::Daemon::help(const std::string &programName)
throw() {
m_stdOut << "Usage: " << programName << " [options]\n"
"\n"
"where options can be:\n"
"\n"
"\t--foreground or -f \tRemain in the Foreground\n"
"\t--config <config-file> or -c \tConfiguration file\n"
"\t--metrics or -m \tEnable metrics collection\n"
"\t--help or -h \tPrint this help and exit\n"
"\n"
"Comments to: Castor.Support@cern.ch\n";
}
//------------------------------------------------------------------------------
// getServerName
//------------------------------------------------------------------------------
const std::string &castor::server::Daemon::getServerName() const throw() {
return m_log.getProgramName();
}
//------------------------------------------------------------------------------
// getForeground
//------------------------------------------------------------------------------
bool castor::server::Daemon::getForeground() const
{
if(!m_commandLineHasBeenParsed) {
castor::exception::CommandLineNotParsed ex;
ex.getMessage() <<
"Failed to determine whether or not the daemon should run in the"
" foreground because the command-line has not yet been parsed";
throw