CommunicationState6::CommunicationState6(const IOServicePtr& io_service,
const HAConfigPtr& config)
: CommunicationState(io_service, config), connecting_clients_(),
- mutex_(new mutex()){
+ mutex_(new mutex()) {
}
void
///
/// 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 modifyPokeTime(const long secs);
+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);
-protected:
-
/// @brief Returns duration between the poke time and current time.
///
+ /// Should be called in a thread safe context.
+ ///
/// @return Duration between the poke time and current time.
int64_t getDurationInMillisecsInternal() const;
// 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);
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 capablity of @c Lease4.
+/// validation capability of @c Lease4.
class CSVLeaseFile4 : public isc::util::VersionedCSVFile, public LeaseFileStats {
public:
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 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::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 capablity of @c Lease6.
+/// validation capability of @c Lease6.
class CSVLeaseFile6 : public isc::util::VersionedCSVFile, public LeaseFileStats {
public:
/// error.
///
/// @param lease Structure representing a DHCPv6 lease.
- /// @throw BadValue if the lease to be written has an empty DUID and is
- /// whose state is not STATE_DECLINED.
+ /// @throw BadValue if the lease to be written has an empty DUID and is not
+ /// in 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 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
}
}
+ // unlock mutex so that the callback can be safely processed.
+ if (MultiThreadingMgr::instance().getMode()) {
+ mutex_.unlock();
+ }
+
try {
// The callback should take care of its own exceptions but one
// never knows.
} catch (...) {
}
+ // lock mutex so that processing can continue.
+ if (MultiThreadingMgr::instance().getMode()) {
+ mutex_.lock();
+ }
+
// If we're not requesting connection persistence, we should close the socket.
// We're going to reconnect for the next transaction.
if (!current_request_->isPersistent()) {