// We only check external sockets if select detected an event.
if (result > 0) {
- // Check for receiver thread read errors.
- if (dhcp_receiver_->isReady(WatchedThread::ERROR)) {
- string msg = dhcp_receiver_->getLastError();
- dhcp_receiver_->clearReady(WatchedThread::ERROR);
- isc_throw(SocketReadError, msg);
+ {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
+ // Check for receiver thread read errors.
+ if (dhcp_receiver_->isReady(WatchedThread::ERROR)) {
+ string msg = dhcp_receiver_->getLastError();
+ dhcp_receiver_->clearReady(WatchedThread::ERROR);
+ isc_throw(SocketReadError, msg);
+ }
}
// Let's find out which external socket has the data
}
// If we're here it should only be because there are DHCP packets waiting.
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
Pkt4Ptr pkt = getPacketQueue4()->dequeuePacket();
if (!pkt) {
dhcp_receiver_->clearReady(WatchedThread::READY);
// We only check external sockets if select detected an event.
if (result > 0) {
- // Check for receiver thread read errors.
- if (dhcp_receiver_->isReady(WatchedThread::ERROR)) {
- string msg = dhcp_receiver_->getLastError();
- dhcp_receiver_->clearReady(WatchedThread::ERROR);
- isc_throw(SocketReadError, msg);
+ {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
+ // Check for receiver thread read errors.
+ if (dhcp_receiver_->isReady(WatchedThread::ERROR)) {
+ string msg = dhcp_receiver_->getLastError();
+ dhcp_receiver_->clearReady(WatchedThread::ERROR);
+ isc_throw(SocketReadError, msg);
+ }
}
// Let's find out which external socket has the data
}
// If we're here it should only be because there are DHCP packets waiting.
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
Pkt6Ptr pkt = getPacketQueue6()->dequeuePacket();
if (!pkt) {
dhcp_receiver_->clearReady(WatchedThread::READY);
} else if (result < 0) {
// This thread should not get signals?
if (errno != EINTR) {
- // Signal the error to receive4.
- dhcp_receiver_->setError(strerror(errno));
+ {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
+ // Signal the error to receive4.
+ dhcp_receiver_->setError(strerror(errno));
+ }
// We need to sleep in case of the error condition to
// prevent the thread from tight looping when result
// gets negative.
}
}
} catch (const std::exception& ex) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError(string(ex.what()) + " error: " + strerror(errno));
} catch (...) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError("receive failed");
}
}
} else if (result < 0) {
// This thread should not get signals?
if (errno != EINTR) {
- // Signal the error to receive6.
- dhcp_receiver_->setError(strerror(errno));
+ {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
+ // Signal the error to receive6.
+ dhcp_receiver_->setError(strerror(errno));
+ }
// We need to sleep in case of the error condition to
// prevent the thread from tight looping when result
// gets negative.
}
}
} catch (const std::exception& ex) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError(string(ex.what()) + " error: " + strerror(errno));
} catch (...) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError("receive failed");
}
}
int result = ioctl(socket_info.sockfd_, FIONREAD, &len);
if (result < 0) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
// Signal the error to receive4.
dhcp_receiver_->setError(strerror(errno));
return;
try {
pkt = packet_filter_->receive(iface, socket_info);
} catch (const std::exception& ex) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError(strerror(errno));
} catch (...) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError("packet filter receive() failed");
}
if (pkt) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
getPacketQueue4()->enqueuePacket(pkt, socket_info);
dhcp_receiver_->markReady(WatchedThread::READY);
}
int result = ioctl(socket_info.sockfd_, FIONREAD, &len);
if (result < 0) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
// Signal the error to receive6.
dhcp_receiver_->setError(strerror(errno));
return;
try {
pkt = packet_filter6_->receive(socket_info);
} catch (const std::exception& ex) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError(ex.what());
} catch (...) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
dhcp_receiver_->setError("packet filter receive() failed");
}
if (pkt) {
+ std::lock_guard<std::mutex> lk(receiver_mutex_);
getPacketQueue6()->enqueuePacket(pkt, socket_info);
dhcp_receiver_->markReady(WatchedThread::READY);
}
/// setPacketFilter method.
PktFilter6Ptr packet_filter6_;
- /// @brief Contains list of callbacks for external sockets
+ /// @brief Contains list of callbacks for external sockets.
SocketCallbackInfoContainer callbacks_;
- /// @brief Mutex to protect callbacks_ against concurrent access
+ /// @brief Mutex to protect callbacks_ against concurrent access.
std::mutex callbacks_mutex_;
/// @brief Indicates if the IfaceMgr is in the test mode.
/// executed, otherwise the @ref detectIfaces will return immediately.
DetectCallback detect_callback_;
- /// @brief Allows to use loopback
+ /// @brief Allows to use loopback.
bool allow_loopback_;
- /// @brief Manager for DHCPv4 packet implementations and queues
+ /// @brief Manager for DHCPv4 packet implementations and queues.
PacketQueueMgr4Ptr packet_queue_mgr4_;
- /// @brief Manager for DHCPv6 packet implementations and queues
+ /// @brief Manager for DHCPv6 packet implementations and queues.
PacketQueueMgr6Ptr packet_queue_mgr6_;
/// @brief DHCP packet receiver.
isc::util::WatchedThreadPtr dhcp_receiver_;
+ /// @brief Mutex to protect receiver against concurrent access.
+ std::mutex receiver_mutex_;
+
/// @brief The FDEventHandler instance.
util::FDEventHandlerPtr fd_event_handler_;