13#include <boost/algorithm/string/predicate.hpp>
24 if (boost::iequals(protocol_str,
"UDP")) {
28 if (boost::iequals(protocol_str,
"TCP")) {
33 "Invalid NameChangeRequest protocol: " << protocol_str);
46 std::ostringstream stream;
47 stream <<
"UNKNOWN(" << protocol <<
")";
48 return (stream.str());
54 : listening_(false), io_pending_(false), recv_handler_(recv_handler) {
116 (*recv_handler_)(result, ncr);
117 }
catch (
const std::exception& ex) {
145 (*recv_handler_)(
ERROR, empty);
146 }
catch (
const std::exception& ex) {
158 size_t send_queue_max)
159 : sending_(false), send_handler_(send_handler),
160 send_queue_max_(send_queue_max), mutex_(new mutex()) {
176 lock_guard<mutex> lock(*mutex_);
177 startSendingInternal(io_service);
179 startSendingInternal(io_service);
190 ncr_to_send_.reset();
214 }
catch (
const std::exception& ex) {
235 }
catch (
const std::exception& ex) {
257 lock_guard<mutex> lock(*mutex_);
258 sendRequestInternal(ncr);
260 sendRequestInternal(ncr);
266 if (send_queue_.size() >= send_queue_max_) {
268 "send queue has reached maximum capacity: "
273 send_queue_.push_back(ncr);
290 if (!send_queue_.empty()) {
291 ncr_to_send_ = send_queue_.front();
305 lock_guard<mutex> lock(*mutex_);
306 invokeSendHandlerInternal(result);
308 invokeSendHandlerInternal(result);
317 send_queue_.pop_front();
326 (*send_handler_)(result, ncr_to_send_);
327 }
catch (
const std::exception& ex) {
333 ncr_to_send_.reset();
355 (*send_handler_)(
ERROR, ncr_to_send_);
356 }
catch (
const std::exception& ex) {
366 lock_guard<mutex> lock(*mutex_);
374NameChangeSender::skipNextInternal() {
375 if (!send_queue_.empty()) {
377 send_queue_.pop_front();
388 lock_guard<mutex> lock(*mutex_);
399 " queue size must be greater than zero");
402 send_queue_max_ = new_max;
408 lock_guard<mutex> lock(*mutex_);
409 return (getQueueSizeInternal());
411 return (getQueueSizeInternal());
416NameChangeSender::getQueueSizeInternal()
const {
417 return (send_queue_.size());
423 lock_guard<mutex> lock(*mutex_);
424 return (peekAtInternal(index));
426 return (peekAtInternal(index));
431NameChangeSender::peekAtInternal(
const size_t index)
const {
432 auto size = getQueueSizeInternal();
435 "NameChangeSender::peekAt peek beyond end of queue attempted"
436 <<
" index: " << index <<
" queue size: " << size);
439 return (send_queue_.at(index));
445 lock_guard<mutex> lock(*mutex_);
446 return ((ncr_to_send_) ?
true :
false);
448 return ((ncr_to_send_) ? true :
false);
454 if (source_sender.amSending()) {
456 " source sender is actively sending");
461 " target sender is actively sending");
466 " source queue count exceeds target queue max");
470 lock_guard<mutex> lock(*mutex_);
471 assumeQueueInternal(source_sender);
473 assumeQueueInternal(source_sender);
479 if (!send_queue_.empty()) {
481 " target queue is not empty");
484 send_queue_.swap(source_sender.getSendQueue());
496 " sender io service is null");
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when a function is not implemented.
virtual void open(const isc::asiolink::IOServicePtr &io_service)=0
Abstract method which opens the IO source for reception.
boost::shared_ptr< RequestReceiveHandler > RequestReceiveHandlerPtr
Defines a smart pointer to an instance of a request receive handler.
void stopListening()
Closes the IO source and stops listen logic.
virtual void close()=0
Abstract method which closes the IO source.
NameChangeListener(RequestReceiveHandlerPtr recv_handler)
Constructor.
virtual void doReceive()=0
Initiates an IO layer asynchronous read.
void invokeRecvHandler(const Result result, NameChangeRequestPtr &ncr)
Calls the NCR receive handler registered with the listener.
bool amListening() const
Returns true if the listener is listening, false otherwise.
Result
Defines the outcome of an asynchronous NCR receive.
void receiveNext()
Initiates an asynchronous receive.
void startListening(const isc::asiolink::IOServicePtr &io_service)
Prepares the IO for reception and initiates the first receive.
Abstract interface for sending NameChangeRequests.
asiolink::IOServicePtr io_service_
Pointer to the IOService currently being used by the sender.
void stopSending()
Closes the IO sink and stops send logic.
virtual int getSelectFd()=0
Returns a file descriptor suitable for use with select.
void startSending(const isc::asiolink::IOServicePtr &io_service)
Prepares the IO for transmission.
NameChangeSender(RequestSendHandlerPtr send_handler, size_t send_queue_max=MAX_QUEUE_DEFAULT)
Constructor.
void assumeQueue(NameChangeSender &source_sender)
Move all queued requests from a given sender into the send queue.
size_t getQueueMaxSize() const
Returns the maximum number of entries allowed in the send queue.
size_t getQueueSize() const
Returns the number of entries currently in the send queue.
const NameChangeRequestPtr & peekAt(const size_t index) const
Returns the entry at a given position in the queue.
virtual bool ioReady()=0
Returns whether or not the sender has IO ready to process.
void skipNext()
Removes the request at the front of the send queue.
boost::shared_ptr< RequestSendHandler > RequestSendHandlerPtr
Defines a smart pointer to an instance of a request send handler.
void clearSendQueue()
Flushes all entries in the send queue.
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
virtual void doSend(NameChangeRequestPtr &ncr)=0
Initiates an IO layer asynchronous send.
void setQueueMaxSize(const size_t new_max)
Sets the maximum queue size to the given value.
void invokeSendHandler(const NameChangeSender::Result result)
Calls the NCR send completion handler registered with the sender.
virtual void open(const isc::asiolink::IOServicePtr &io_service)=0
Abstract method which opens the IO sink for transmission.
virtual void close()=0
Abstract method which closes the IO sink.
void sendRequest(NameChangeRequestPtr &ncr)
Queues the given request to be sent.
virtual void runReadyIO()
Processes sender IO events.
bool isSendInProgress() const
Returns true when a send is in progress.
Result
Defines the outcome of an asynchronous NCR send.
void sendNext()
Dequeues and sends the next request on the send queue in a thread safe context.
Exception thrown if an NcrListenerError encounters a general error.
Exception thrown if an error occurs during IO source open.
Exception thrown if an error occurs initiating an IO receive.
Thrown when a NameChangeSender encounters an error.
Exception thrown if an error occurs during IO source open.
Exception thrown if an error occurs initiating an IO send.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
isc::log::Logger dhcp_ddns_logger("libdhcp-ddns")
Defines the logger used within lib dhcp_ddns.
NameChangeProtocol stringToNcrProtocol(const std::string &protocol_str)
Function which converts text labels to NameChangeProtocol enums.
const isc::log::MessageID DHCP_DDNS_NCR_SEND_CLOSE_ERROR
const isc::log::MessageID DHCP_DDNS_NCR_SEND_NEXT_ERROR
const isc::log::MessageID DHCP_DDNS_NCR_FLUSH_IO_ERROR
NameChangeProtocol
Defines the list of socket protocols supported.
std::string ncrProtocolToString(NameChangeProtocol protocol)
Function which converts NameChangeProtocol enums to text labels.
const isc::log::MessageID DHCP_DDNS_UNCAUGHT_NCR_SEND_HANDLER_ERROR
const isc::log::MessageID DHCP_DDNS_UNCAUGHT_NCR_RECV_HANDLER_ERROR
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP_DDNS_NCR_LISTEN_CLOSE_ERROR
const isc::log::MessageID DHCP_DDNS_NCR_RECV_NEXT_ERROR
Defines the logger used by the top-level component of kea-lfc.
This file defines abstract classes for exchanging NameChangeRequests.