Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pavel Zhukov
Kea
Commits
bf944144
Commit
bf944144
authored
Feb 01, 2011
by
Michal 'vorner' Vaner
Browse files
[trac537] Some explaining comments
parent
d1971c14
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/asiolink/internal/udpdns.h
View file @
bf944144
...
...
@@ -173,6 +173,15 @@ public:
private:
enum
{
MAX_LENGTH
=
4096
};
/**
* \brief Internal state and data.
*
* We use the pimple design pattern, but not because we need to hide
* internal data. This class and whole header is for private use anyway.
* It turned out that UDPServer is copied a lot, because it is a coroutine.
* This way the overhead of copying is lower, we copy only one shared
* pointer instead of about 10 of them.
*/
class
Data
;
boost
::
shared_ptr
<
Data
>
data_
;
};
...
...
src/lib/asiolink/udpdns.cc
View file @
bf944144
...
...
@@ -48,7 +48,20 @@ using namespace isc::dns;
namespace
asiolink
{
/*
* Some of the member variables here are shared_ptrs and some are
* auto_ptrs. There will be one instance of Data for the lifetime
* of packet. The variables that are state only for a single packet
* use auto_ptr, as it is more lightweight. In the case of shared
* configuration (eg. the callbacks, socket), we use shared_ptrs.
*/
struct
UDPServer
::
Data
{
/*
* Constructor from parameters passed to UDPServer constructor.
* This instance will not be used to retrieve and answer the actual
* query, it will only hold parameters until we wait for the
* first packet. But we do initialize the socket in here.
*/
Data
(
io_service
&
io_service
,
const
ip
::
address
&
addr
,
const
uint16_t
port
,
SimpleCallback
*
checkin
,
DNSLookup
*
lookup
,
DNSAnswer
*
answer
)
:
io_
(
io_service
),
done_
(
false
),
checkin_callback_
(
checkin
),
...
...
@@ -65,6 +78,13 @@ struct UDPServer::Data {
socket_
->
bind
(
udp
::
endpoint
(
addr
,
port
));
}
/*
* Copy constructor. Default one would probably do, but it is unnecessary
* to copy many of the member variables every time we fork to handle
* another packet.
*
* We also allocate data for receiving the packet here.
*/
Data
(
const
Data
&
other
)
:
io_
(
other
.
io_
),
socket_
(
other
.
socket_
),
done_
(
false
),
checkin_callback_
(
other
.
checkin_callback_
),
...
...
@@ -94,7 +114,7 @@ struct UDPServer::Data {
// constructor, or in the function operator while processing a query.
// Repeated allocations from the heap for every incoming query is
// clearly a performance issue; this must be optimized in the future.
// The plan is to have a structure pre-allocate several "
server st
at
e
"
// The plan is to have a structure pre-allocate several "
D
at
a
"
// objects which can be pulled off a free list and placed on an in-use
// list whenever a query comes in. This will serve the dual purpose
// of improving performance and guaranteeing that state information
...
...
@@ -141,7 +161,8 @@ struct UDPServer::Data {
/// The following functions implement the \c UDPServer class.
///
/// The constructor
/// The constructor. It just creates new internal state object
/// and lets it handle the initialization.
UDPServer
::
UDPServer
(
io_service
&
io_service
,
const
ip
::
address
&
addr
,
const
uint16_t
port
,
SimpleCallback
*
checkin
,
DNSLookup
*
lookup
,
DNSAnswer
*
answer
)
:
...
...
@@ -158,6 +179,11 @@ UDPServer::operator()(error_code ec, size_t length) {
CORO_REENTER
(
this
)
{
do
{
/*
* This is preparation for receiving a packet. We get a new
* state object for the lifetime of the next packet to come.
* It allocates the buffers to receive data into.
*/
data_
.
reset
(
new
Data
(
*
data_
));
do
{
...
...
@@ -171,10 +197,16 @@ UDPServer::operator()(error_code ec, size_t length) {
data_
->
bytes_
=
length
;
/// Fork the coroutine by creating a copy of this one and
/// scheduling it on the ASIO service queue. The parent
/// will continue listening for DNS packets while the child
/// processes the one that has just arrived.
/*
* We fork the coroutine now. One (the child) will keep
* the current state and handle the packet, then die and
* drop ownership of the state. The other (parent) will just
* go into the loop again and replace the current state with
* a new one for a new object.
*
* Actually, both of the coroutines will be a copy of this
* one, but that's just internal implementation detail.
*/
CORO_FORK
data_
->
io_
.
post
(
UDPServer
(
*
this
));
}
while
(
is_parent
());
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment