Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
a1bdf3c9
Commit
a1bdf3c9
authored
Jul 27, 2016
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ensure only one ASIO async operation is pending
parent
b79a5b38
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
45 additions
and
6 deletions
+45
-6
libcaf_io/caf/io/network/asio_multiplexer.hpp
libcaf_io/caf/io/network/asio_multiplexer.hpp
+45
-6
No files found.
libcaf_io/caf/io/network/asio_multiplexer.hpp
View file @
a1bdf3c9
...
...
@@ -142,7 +142,8 @@ public:
ack_writes_
(
false
),
fd_
(
ref
.
service
()),
backend_
(
ref
),
rd_buf_ready_
(
false
)
{
rd_buf_ready_
(
false
),
async_read_pending_
(
false
)
{
configure_read
(
receive_policy
::
at_most
(
1024
));
}
...
...
@@ -230,6 +231,7 @@ public:
/// Activates the stream.
void
activate
(
stream_manager
*
mgr
)
{
reading_
=
true
;
read_loop
(
mgr
);
}
...
...
@@ -254,7 +256,8 @@ private:
}
void
read_loop
(
manager_ptr
mgr
)
{
reading_
=
true
;
if
(
async_read_pending_
)
return
;
if
(
rd_buf_ready_
)
{
rd_buf_ready_
=
false
;
if
(
read_one
(
mgr
.
get
(),
rd_buf_
.
size
()))
...
...
@@ -262,6 +265,7 @@ private:
return
;
}
auto
cb
=
[
=
](
const
error_code
&
ec
,
size_t
read_bytes
)
mutable
{
async_read_pending_
=
false
;
CAF_LOG_TRACE
(
""
);
if
(
!
ec
)
{
// bail out early in case broker passivated stream in the meantime
...
...
@@ -273,15 +277,16 @@ private:
};
switch
(
rd_flag_
)
{
case
receive_policy_flag
:
:
exactly
:
if
(
rd_buf_
.
size
()
<
rd_size_
)
{
if
(
rd_buf_
.
size
()
<
rd_size_
)
rd_buf_
.
resize
(
rd_size_
);
}
async_read_pending_
=
true
;
boost
::
asio
::
async_read
(
fd_
,
boost
::
asio
::
buffer
(
rd_buf_
,
rd_size_
),
cb
);
break
;
case
receive_policy_flag
:
:
at_most
:
if
(
rd_buf_
.
size
()
<
rd_size_
)
rd_buf_
.
resize
(
rd_size_
);
async_read_pending_
=
true
;
fd_
.
async_read_some
(
boost
::
asio
::
buffer
(
rd_buf_
,
rd_size_
),
cb
);
break
;
case
receive_policy_flag
:
:
at_least
:
{
...
...
@@ -321,9 +326,11 @@ private:
}
void
collect_data
(
manager_ptr
mgr
,
size_t
collected_bytes
)
{
async_read_pending_
=
true
;
fd_
.
async_read_some
(
boost
::
asio
::
buffer
(
rd_buf_
.
data
()
+
collected_bytes
,
rd_buf_
.
size
()
-
collected_bytes
),
[
=
](
const
error_code
&
ec
,
size_t
nb
)
mutable
{
async_read_pending_
=
false
;
CAF_LOG_TRACE
(
CAF_ARG
(
nb
));
if
(
!
ec
)
{
auto
sum
=
collected_bytes
+
nb
;
...
...
@@ -339,17 +346,42 @@ private:
});
}
/// Set if read loop was started by user and unset if passivate is called.
bool
reading_
;
/// Set on flush, also indicates that an async_write is pending.
bool
writing_
;
/// Stores whether user requested ACK messages for async writes.
bool
ack_writes_
;
/// TCP socket for this connection.
Socket
fd_
;
/// Configures how chunk sizes are calculated.
receive_policy_flag
rd_flag_
;
/// Minimum, maximum, or exact size of a chunk, depending on `rd_flag_`.
size_t
rd_size_
;
/// Input buffer.
buffer_type
rd_buf_
;
/// Output buffer for ASIO.
buffer_type
wr_buf_
;
/// Swapped with `wr_buf_` before next write. Users write into this buffer
/// as long as `wr_buf_` is processed by ASIO.
buffer_type
wr_offline_buf_
;
/// Reference to our I/O backend.
asio_multiplexer
&
backend_
;
/// Signalizes that a scribe was passivated while an async read was pending.
bool
rd_buf_ready_
;
/// Makes sure no more than one async_read is pending at any given time
bool
async_read_pending_
;
};
/// An acceptor is responsible for accepting incoming connections.
...
...
@@ -370,7 +402,8 @@ public:
backend_
(
am
),
accept_fd_
(
io
),
fd_valid_
(
false
),
fd_
(
io
)
{
fd_
(
io
),
async_accept_pending_
(
false
)
{
// nop
}
...
...
@@ -407,6 +440,7 @@ public:
/// Starts the accept loop.
void
activate
(
manager_type
*
mgr
)
{
accepting_
=
true
;
accept_loop
(
mgr
);
}
...
...
@@ -429,7 +463,8 @@ private:
}
void
accept_loop
(
manager_ptr
mgr
)
{
accepting_
=
true
;
if
(
async_accept_pending_
)
return
;
// accept "cached" connection first
if
(
fd_valid_
)
{
fd_valid_
=
false
;
...
...
@@ -437,8 +472,10 @@ private:
accept_loop
(
std
::
move
(
mgr
));
return
;
}
async_accept_pending_
=
true
;
accept_fd_
.
async_accept
(
fd_
,
[
=
](
const
error_code
&
ec
)
mutable
{
CAF_LOG_TRACE
(
""
);
async_accept_pending_
=
false
;
if
(
!
ec
)
{
// if broker has passivated this in the meantime, cache fd_ for later
if
(
!
accepting_
)
{
...
...
@@ -458,6 +495,8 @@ private:
SocketAcceptor
accept_fd_
;
bool
fd_valid_
;
socket_type
fd_
;
/// Makes sure no more than one async_accept is pending at any given time
bool
async_accept_pending_
;
};
}
// namesapce network
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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