CommunicationState::modifyPokeTime(const long secs) {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- modifyPokeTimeInternal(secs);
+ poke_time_ += boost::posix_time::seconds(secs);
} else {
- modifyPokeTimeInternal(secs);
+ poke_time_ += boost::posix_time::seconds(secs);
}
}
-void
-CommunicationState::modifyPokeTimeInternal(const long secs) {
- poke_time_ += boost::posix_time::seconds(secs);
-}
-
void
CommunicationState::setPartnerState(const std::string& state) {
try {
// Only log the first time we detect a client is unacked.
if (log_unacked) {
unsigned unacked_left = 0;
- if (config_->getMaxUnackedClients() > getUnackedClientsCountInternal()) {
- unacked_left = config_->getMaxUnackedClients() - getUnackedClientsCountInternal();
+ unsigned unacked_total = connecting_clients_.get<1>().count(true);
+ if (config_->getMaxUnackedClients() > unacked_total) {
+ unacked_left = config_->getMaxUnackedClients() - unacked_total;
}
LOG_INFO(ha_logger, HA_COMMUNICATION_INTERRUPTED_CLIENT4_UNACKED)
.arg(message->getLabel())
- .arg(getUnackedClientsCountInternal())
+ .arg(unacked_total)
.arg(unacked_left);
}
}
bool
CommunicationState4::failureDetectedInternal() const {
return ((config_->getMaxUnackedClients() == 0) ||
- (getUnackedClientsCountInternal() > config_->getMaxUnackedClients()));
+ (connecting_clients_.get<1>().count(true) >
+ config_->getMaxUnackedClients()));
}
size_t
CommunicationState4::getConnectingClientsCount() const {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- return (getConnectingClientsCountInternal());
+ return (connecting_clients_.size());
} else {
- return (getConnectingClientsCountInternal());
+ return (connecting_clients_.size());
}
}
-size_t
-CommunicationState4::getConnectingClientsCountInternal() const {
- return (connecting_clients_.size());
-}
-
size_t
CommunicationState4::getUnackedClientsCount() const {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- return (getUnackedClientsCountInternal());
+ return (connecting_clients_.get<1>().count(true));
} else {
- return (getUnackedClientsCountInternal());
+ return (connecting_clients_.get<1>().count(true));
}
}
-size_t
-CommunicationState4::getUnackedClientsCountInternal() const {
- return (connecting_clients_.get<1>().count(true));
-}
-
void
CommunicationState4::clearConnectingClients() {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- clearConnectingClientsInternal();
+ connecting_clients_.clear();
} else {
- clearConnectingClientsInternal();
+ connecting_clients_.clear();
}
}
-void
-CommunicationState4::clearConnectingClientsInternal() {
- connecting_clients_.clear();
-}
-
CommunicationState6::CommunicationState6(const IOServicePtr& io_service,
const HAConfigPtr& config)
: CommunicationState(io_service, config), connecting_clients_(),
// Only log the first time we detect a client is unacked.
if (log_unacked) {
unsigned unacked_left = 0;
- if (config_->getMaxUnackedClients() > getUnackedClientsCountInternal()) {
- unacked_left = config_->getMaxUnackedClients() - getUnackedClientsCountInternal();
+ unsigned unacked_total = connecting_clients_.get<1>().count(true);
+ if (config_->getMaxUnackedClients() > unacked_total) {
+ unacked_left = config_->getMaxUnackedClients() - unacked_total;
}
LOG_INFO(ha_logger, HA_COMMUNICATION_INTERRUPTED_CLIENT6_UNACKED)
.arg(message->getLabel())
- .arg(getUnackedClientsCountInternal())
+ .arg(unacked_total)
.arg(unacked_left);
}
}
bool
CommunicationState6::failureDetectedInternal() const {
return ((config_->getMaxUnackedClients() == 0) ||
- (getUnackedClientsCountInternal() > config_->getMaxUnackedClients()));
+ (connecting_clients_.get<1>().count(true) >
+ config_->getMaxUnackedClients()));
}
size_t
CommunicationState6::getConnectingClientsCount() const {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- return (getConnectingClientsCountInternal());
+ return (connecting_clients_.size());
} else {
- return (getConnectingClientsCountInternal());
+ return (connecting_clients_.size());
}
}
-size_t
-CommunicationState6::getConnectingClientsCountInternal() const {
- return (connecting_clients_.size());
-}
-
size_t
CommunicationState6::getUnackedClientsCount() const {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- return (getUnackedClientsCountInternal());
+ return (connecting_clients_.get<1>().count(true));
} else {
- return (getUnackedClientsCountInternal());
+ return (connecting_clients_.get<1>().count(true));
}
}
-size_t
-CommunicationState6::getUnackedClientsCountInternal() const {
- return (connecting_clients_.get<1>().count(true));
-}
-
void
CommunicationState6::clearConnectingClients() {
if (MultiThreadingMgr::instance().getMode()) {
std::lock_guard<std::mutex> lk(*mutex_);
- clearConnectingClientsInternal();
+ connecting_clients_.clear();
} else {
- clearConnectingClientsInternal();
+ connecting_clients_.clear();
}
}
-void
-CommunicationState6::clearConnectingClientsInternal() {
- connecting_clients_.clear();
-}
-
} // end of namespace isc::ha
} // end of namespace isc
protected:
- /// @brief Modifies poke time by adding seconds to it.
- ///
- /// Used in unittests only.
- ///
- /// Should be called in a thread safe context.
- ///
- /// @param secs number of seconds to be added to the poke time. If
- /// the value is negative it will set the poke time in the past
- /// comparing to current value.
- void modifyPokeTimeInternal(const long secs);
-
/// @brief Returns duration between the poke time and current time.
///
/// Should be called in a thread safe context.
/// otherwise.
virtual bool failureDetectedInternal() const;
- /// @brief Returns the current number of clients which attempted
- /// to get a lease from the partner server.
- ///
- /// Should be called in a thread safe context.
- ///
- /// The returned number is reset to 0 when the server successfully
- /// establishes communication with the partner. The number is
- /// incremented only in the communications interrupted case.
- ///
- /// @return The number of clients including unacked clients.
- virtual size_t getConnectingClientsCountInternal() const;
-
- /// @brief Returns the current number of clients which haven't gotten
- /// a lease from the partner server.
- ///
- /// Should be called in a thread safe context.
- ///
- /// The returned number is reset to 0 when the server successfully
- /// establishes communication with the partner. The number is
- /// incremented only in the communications interrupted case.
- ///
- /// @return Number of unacked clients.
- virtual size_t getUnackedClientsCountInternal() const;
-
/// @brief Removes information about the clients the partner server
/// should respond to while communication with the partner was
/// interrupted.
/// See @c CommunicationState::analyzeMessage for details.
virtual void clearConnectingClients();
- /// @brief Removes information about the clients the partner server
- /// should respond to while communication with the partner was
- /// interrupted.
- ///
- /// Should be called in a thread safe context.
- ///
- /// See @c CommunicationState::analyzeMessage for details.
- virtual void clearConnectingClientsInternal();
-
/// @brief Structure holding information about the client which has
/// send the packet being analyzed.
struct ConnectingClient4 {
/// otherwise.
virtual bool failureDetectedInternal() const;
- /// @brief Returns the current number of clients which attempted
- /// to get a lease from the partner server.
- ///
- /// Should be called in a thread safe context.
- ///
- /// The returned number is reset to 0 when the server successfully
- /// establishes communication with the partner. The number is
- /// incremented only in the communications interrupted case.
- ///
- /// @return The number of clients including unacked clients.
- virtual size_t getConnectingClientsCountInternal() const;
-
- /// @brief Returns the current number of clients which haven't gotten
- /// a lease from the partner server.
- ///
- /// Should be called in a thread safe context.
- ///
- /// The returned number is reset to 0 when the server successfully
- /// establishes communication with the partner. The number is
- /// incremented only in the communications interrupted case.
- ///
- /// @return Number of unacked clients.
- virtual size_t getUnackedClientsCountInternal() const;
-
/// @brief Removes information about the clients the partner server
/// should respond to while communication with the partner was
/// interrupted.
/// See @c CommunicationState::analyzeMessage for details.
virtual void clearConnectingClients();
- /// @brief Removes information about the clients the partner server
- /// should respond to while communication with the partner was
- /// interrupted.
- ///
- /// Should be called in a thread safe context.
- ///
- /// See @c CommunicationState::analyzeMessage for details.
- virtual void clearConnectingClientsInternal();
-
/// @brief Structure holding information about a client which
/// sent a packet being analyzed.
struct ConnectingClient6 {
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
-
#include <dhcpsrv/csv_lease_file4.h>
-#include <util/multi_threading_mgr.h>
-
#include <ctime>
using namespace isc::asiolink;
void
CSVLeaseFile4::open(const bool seek_to_end) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- openInternal(seek_to_end);
- } else {
- openInternal(seek_to_end);
- }
-}
-
-void
-CSVLeaseFile4::openInternal(const bool seek_to_end) {
// Call the base class to open the file
VersionedCSVFile::open(seek_to_end);
clearStatistics();
}
-void
-CSVLeaseFile4::close() {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- closeInternal();
- } else {
- closeInternal();
- }
-}
-
-void
-CSVLeaseFile4::closeInternal() {
- // Call the base class to close the file
- VersionedCSVFile::close();
-}
-
void
CSVLeaseFile4::append(const Lease4& lease) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- appendInternal(lease);
- } else {
- appendInternal(lease);
- }
-}
-
-void
-CSVLeaseFile4::appendInternal(const Lease4& lease) {
// Bump the number of write attempts
++writes_;
bool
CSVLeaseFile4::next(Lease4Ptr& lease) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- return (nextInternal(lease));
- } else {
- return (nextInternal(lease));
- }
-}
-
-bool
-CSVLeaseFile4::nextInternal(Lease4Ptr& lease) {
// Bump the number of read attempts
++reads_;
/// The @c Lease4 is a structure that should be itself responsible for this
/// validation (see http://oldkea.isc.org/ticket/2405). However, when #2405
/// is implemented, the @c next function may need to be updated to use the
-/// validation capability of @c Lease4.
+/// validation capablity of @c Lease4.
class CSVLeaseFile4 : public isc::util::VersionedCSVFile, public LeaseFileStats {
public:
/// the base class may do so.
virtual void open(const bool seek_to_end = false);
- /// @brief Closes the lease file.
- ///
- /// This function should hide instead of overwrite the base class function.
- virtual void close();
-
/// @brief Appends the lease record to the CSV file.
///
/// This function doesn't throw exceptions itself. In theory, exceptions
private:
- /// @brief Opens a lease file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// This function calls the base class open to do the
- /// work of opening a file. It is used to clear any
- /// statistics associated with any previous use of the file
- /// While it doesn't throw any exceptions of its own
- /// the base class may do so.
- virtual void openInternal(const bool seek_to_end = false);
-
- /// @brief Closes the lease file.
- ///
- /// Should be called in a thread safe context.
- virtual void closeInternal();
-
- /// @brief Appends the lease record to the CSV file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// This function doesn't throw exceptions itself. In theory, exceptions
- /// are possible when the index of the indexes of the values being written
- /// to the file are invalid. However, this would have been a programming
- /// error.
- ///
- /// @param lease Structure representing a DHCPv4 lease.
- /// @throw BadValue if the lease has no hardware address, no client id and
- /// is not in STATE_DECLINED.
- void appendInternal(const Lease4& lease);
-
- /// @brief Reads next lease from the CSV file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// If this function hits an error during lease read, it sets the error
- /// message using @c CSVFile::setReadMsg and returns false. The error
- /// string may be read using @c CSVFile::getReadMsg.
- ///
- /// Treats rows without a hardware address or a client id when their
- /// state is not STATE_DECLINED as an error.
- ///
- /// This function is exception safe.
- ///
- /// @param [out] lease Pointer to the lease read from CSV file or
- /// NULL pointer if lease hasn't been read.
- ///
- /// @return Boolean value indicating that the new lease has been
- /// read from the CSV file (if true), or that the error has occurred
- /// (false).
- ///
- /// @todo Make sure that the values read from the file are correct.
- /// The appropriate @c Lease4 validation mechanism should be used once
- /// ticket http://oldkea.isc.org/ticket/2405 is implemented.
- bool nextInternal(Lease4Ptr& lease);
-
/// @brief Initializes columns of the CSV file holding leases.
///
/// This function initializes the following columns:
data::ConstElementPtr readContext(const util::CSVRow& row);
//@}
- /// @brief Mutex to protect the internal state.
- std::mutex mutex_;
};
} // namespace isc::dhcp
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
-
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/csv_lease_file6.h>
-#include <util/multi_threading_mgr.h>
-
#include <ctime>
using namespace isc::asiolink;
void
CSVLeaseFile6::open(const bool seek_to_end) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- openInternal(seek_to_end);
- } else {
- openInternal(seek_to_end);
- }
-}
-
-void
-CSVLeaseFile6::close() {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- closeInternal();
- } else {
- closeInternal();
- }
-}
-
-void
-CSVLeaseFile6::closeInternal() {
- // Call the base class to close the file
- VersionedCSVFile::close();
-}
-
-void
-CSVLeaseFile6::openInternal(const bool seek_to_end) {
// Call the base class to open the file
VersionedCSVFile::open(seek_to_end);
void
CSVLeaseFile6::append(const Lease6& lease) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- appendInternal(lease);
- } else {
- appendInternal(lease);
- }
-}
-
-void
-CSVLeaseFile6::appendInternal(const Lease6& lease) {
// Bump the number of write attempts
++writes_;
bool
CSVLeaseFile6::next(Lease6Ptr& lease) {
- if (MultiThreadingMgr::instance().getMode()) {
- std::lock_guard<std::mutex> lock(mutex_);
- return (nextInternal(lease));
- } else {
- return (nextInternal(lease));
- }
-}
-
-bool
-CSVLeaseFile6::nextInternal(Lease6Ptr& lease) {
// Bump the number of read attempts
++reads_;
/// The @c Lease6 is a structure that should be itself responsible for this
/// validation (see http://oldkea.isc.org/ticket/2405). However, when #2405
/// is implemented, the @c next function may need to be updated to use the
-/// validation capability of @c Lease6.
+/// validation capablity of @c Lease6.
class CSVLeaseFile6 : public isc::util::VersionedCSVFile, public LeaseFileStats {
public:
/// the base class may do so.
virtual void open(const bool seek_to_end = false);
- /// @brief Closes the lease file.
- ///
- /// This function should hide instead of overwrite the base class function.
- virtual void close();
-
/// @brief Appends the lease record to the CSV file.
///
/// This function doesn't throw exceptions itself. In theory, exceptions
/// error.
///
/// @param lease Structure representing a DHCPv6 lease.
- /// @throw BadValue if the lease to be written has an empty DUID and is not
- /// in STATE_DECLINED.
+ /// @throw BadValue if the lease to be written has an empty DUID and is
+ /// whose state is not STATE_DECLINED.
void append(const Lease6& lease);
/// @brief Reads next lease from the CSV file.
private:
- /// @brief Opens a lease file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// This function calls the base class open to do the
- /// work of opening a file. It is used to clear any
- /// statistics associated with any previous use of the file
- /// While it doesn't throw any exceptions of its own
- /// the base class may do so.
- virtual void openInternal(const bool seek_to_end = false);
-
- /// @brief Closes the lease file.
- ///
- /// Should be called in a thread safe context.
- virtual void closeInternal();
-
- /// @brief Appends the lease record to the CSV file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// This function doesn't throw exceptions itself. In theory, exceptions
- /// are possible when the index of the indexes of the values being written
- /// to the file are invalid. However, this would have been a programming
- /// error.
- ///
- /// @param lease Structure representing a DHCPv6 lease.
- /// @throw BadValue if the lease to be written has an empty DUID and is not
- /// in STATE_DECLINED.
- void appendInternal(const Lease6& lease);
-
- /// @brief Reads next lease from the CSV file.
- ///
- /// Should be called in a thread safe context.
- ///
- /// If this function hits an error during lease read, it sets the error
- /// message using @c CSVFile::setReadMsg and returns false. The error
- /// string may be read using @c CSVFile::getReadMsg.
- ///
- /// This function is exception safe.
- ///
- /// @param [out] lease Pointer to the lease read from CSV file or
- /// NULL pointer if lease hasn't been read.
- ///
- /// @return Boolean value indicating that the new lease has been
- /// read from the CSV file (if true), or that the error has occurred
- /// (false).
- ///
- /// @todo Make sure that the values read from the file are correct.
- /// The appropriate @c Lease6 validation mechanism should be used once
- /// ticket http://oldkea.isc.org/ticket/2405 is implemented.
- bool nextInternal(Lease6Ptr& lease);
-
/// @brief Initializes columns of the CSV file holding leases.
///
/// This function initializes the following columns:
data::ConstElementPtr readContext(const util::CSVRow& row);
//@}
- /// @brief Mutex to protect the internal state.
- std::mutex mutex_;
};
} // namespace isc::dhcp
// Check if we're in the v4 or v6 space and use the appropriate file.
if (lease_file4_) {
+ MultiThreadingCriticalSection cs;
lfcExecute(lease_file4_);
-
} else if (lease_file6_) {
+ MultiThreadingCriticalSection cs;
lfcExecute(lease_file6_);
}
}
/// Before the @c TimerMgr can be used the server process must call
/// @c TimerMgr::setIOService to associate the manager with the IO service
/// that the server is using to its run tasks.
+///
+/// @note Only scheduling new timer (calling @ref setup) and canceling existing
+/// timer (calling @ref cancel) are thread safe.
+/// Registering new timers (calling @ref registerTimer) and unregistering
+/// existing timers (calling @ref unregisterTimer) must be handled before
+/// starting processing threads.
class TimerMgr : public boost::noncopyable {
public:
private:
- /// @brief Returns next queued request for the given URL.
+ /// @brief Process next queued request for the given URL.
///
/// This method should be called in a thread safe context.
///
/// @param url URL for which next queued request should be retrieved.
- /// @param [out] request Pointer to the queued request.
- /// @param [out] response Pointer to the object into which response should
- /// be stored.
- /// @param request_timeout Requested timeout for the transaction.
- /// @param callback Pointer to the user callback for this request.
- /// @param connect_callback Pointer to the user callback invoked when
- /// the client connects to the server.
- /// @param close_callback Pointer to the user callback invoked when
- /// the client closes the connection to the server.
- ///
- /// @return true if the request for the given URL has been retrieved,
+ ///
+ /// @return true if the request for the given URL has been processed,
/// false if there are no more requests queued for this URL.
bool processNextRequestInternal(const Url& url) {
// Check if there is a queue for this URL. If there is no queue, there
struct RequestDescriptor {
/// @brief Constructor.
///
+ /// @param conn Pointer to the connection.
/// @param request Pointer to the request to be sent.
/// @param response Pointer to the object into which the response will
/// be stored.
current_callback_ = HttpClient::RequestHandler();
}
-
void
Connection::closeCallback(const bool clear) {
if (close_callback_) {