Skip to content

Commit 7804ed1

Browse files
fakeshadowrobjtede
andauthored
block and wait for accept thread to exit. (#443)
Co-authored-by: Rob Ede <[email protected]>
1 parent 2a54065 commit 7804ed1

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

actix-server/CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changes
22

33
## Unreleased - 2021-xx-xx
4+
- Wait for accept thread to stop before sending completion signal. [#443]
5+
6+
[#443]: https://github.com/actix/actix-net/pull/443
47

58

69
## 2.0.0 - 2022-01-19

actix-server/src/accept.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Accept {
4141
pub(crate) fn start(
4242
sockets: Vec<(usize, MioListener)>,
4343
builder: &ServerBuilder,
44-
) -> io::Result<(WakerQueue, Vec<WorkerHandleServer>)> {
44+
) -> io::Result<(WakerQueue, Vec<WorkerHandleServer>, thread::JoinHandle<()>)> {
4545
let handle_server = ServerHandle::new(builder.cmd_tx.clone());
4646

4747
// construct poll instance and its waker
@@ -73,12 +73,12 @@ impl Accept {
7373
handle_server,
7474
)?;
7575

76-
thread::Builder::new()
76+
let accept_handle = thread::Builder::new()
7777
.name("actix-server acceptor".to_owned())
7878
.spawn(move || accept.poll_with(&mut sockets))
7979
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
8080

81-
Ok((waker_queue, handles_server))
81+
Ok((waker_queue, handles_server, accept_handle))
8282
}
8383

8484
fn new_with_sockets(

actix-server/src/server.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{
33
io, mem,
44
pin::Pin,
55
task::{Context, Poll},
6+
thread,
67
time::Duration,
78
};
89

@@ -158,6 +159,7 @@ impl Future for Server {
158159

159160
pub struct ServerInner {
160161
worker_handles: Vec<WorkerHandleServer>,
162+
accept_handle: Option<thread::JoinHandle<()>>,
161163
worker_config: ServerWorkerConfig,
162164
services: Vec<Box<dyn InternalServiceFactory>>,
163165
waker_queue: WakerQueue,
@@ -205,7 +207,7 @@ impl ServerInner {
205207
);
206208
}
207209

208-
let (waker_queue, worker_handles) = Accept::start(sockets, &builder)?;
210+
let (waker_queue, worker_handles, accept_handle) = Accept::start(sockets, &builder)?;
209211

210212
let mux = ServerEventMultiplexer {
211213
signal_fut: (builder.listen_os_signals).then(Signals::new),
@@ -214,6 +216,7 @@ impl ServerInner {
214216

215217
let server = ServerInner {
216218
waker_queue,
219+
accept_handle: Some(accept_handle),
217220
worker_handles,
218221
worker_config: builder.worker_config,
219222
services: builder.factories,
@@ -243,7 +246,8 @@ impl ServerInner {
243246
} => {
244247
self.stopping = true;
245248

246-
// stop accept thread
249+
// Signal accept thread to stop.
250+
// Signal is non-blocking; we wait for thread to stop later.
247251
self.waker_queue.wake(WakerInterest::Stop);
248252

249253
// send stop signal to workers
@@ -258,6 +262,13 @@ impl ServerInner {
258262
let _ = join_all(workers_stop).await;
259263
}
260264

265+
// wait for accept thread stop
266+
self.accept_handle
267+
.take()
268+
.unwrap()
269+
.join()
270+
.expect("Accept thread must not panic in any case");
271+
261272
if let Some(tx) = completion {
262273
let _ = tx.send(());
263274
}

0 commit comments

Comments
 (0)