Merge pull request #3903 from ethcore/test-mem-limit-deadlock
fix deadlock in queue drop
This commit is contained in:
commit
18965be047
@ -137,7 +137,7 @@ pub struct VerificationQueue<K: Kind> {
|
|||||||
max_queue_size: usize,
|
max_queue_size: usize,
|
||||||
max_mem_use: usize,
|
max_mem_use: usize,
|
||||||
scale_verifiers: bool,
|
scale_verifiers: bool,
|
||||||
verifier_handles: Vec<JoinHandle<()>>,
|
verifier_handles: Vec<JoinHandle<()>>,
|
||||||
state: Arc<(Mutex<State>, Condvar)>,
|
state: Arc<(Mutex<State>, Condvar)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +225,8 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
|
|
||||||
let num_cpus = ::num_cpus::get();
|
let num_cpus = ::num_cpus::get();
|
||||||
let max_verifiers = min(num_cpus, MAX_VERIFIERS);
|
let max_verifiers = min(num_cpus, MAX_VERIFIERS);
|
||||||
let default_amount = max(1, min(max_verifiers, config.verifier_settings.num_verifiers));
|
let default_amount = max(1, min(max_verifiers, config.verifier_settings.num_verifiers));
|
||||||
let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new()));
|
let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new()));
|
||||||
let mut verifier_handles = Vec::with_capacity(max_verifiers);
|
let mut verifier_handles = Vec::with_capacity(max_verifiers);
|
||||||
|
|
||||||
debug!(target: "verification", "Allocating {} verifiers, {} initially active", max_verifiers, default_amount);
|
debug!(target: "verification", "Allocating {} verifiers, {} initially active", max_verifiers, default_amount);
|
||||||
@ -248,11 +248,11 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
panic_handler.catch_panic(move || {
|
panic_handler.catch_panic(move || {
|
||||||
VerificationQueue::verify(
|
VerificationQueue::verify(
|
||||||
verification,
|
verification,
|
||||||
engine,
|
engine,
|
||||||
wait,
|
wait,
|
||||||
ready,
|
ready,
|
||||||
empty,
|
empty,
|
||||||
state,
|
state,
|
||||||
i,
|
i,
|
||||||
)
|
)
|
||||||
@ -299,11 +299,11 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
|
|
||||||
debug!(target: "verification", "verifier {} sleeping", id);
|
debug!(target: "verification", "verifier {} sleeping", id);
|
||||||
state.1.wait(&mut cur_state);
|
state.1.wait(&mut cur_state);
|
||||||
debug!(target: "verification", "verifier {} waking up", id);
|
debug!(target: "verification", "verifier {} waking up", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let State::Exit = *cur_state {
|
if let State::Exit = *cur_state {
|
||||||
debug!(target: "verification", "verifier {} exiting", id);
|
debug!(target: "verification", "verifier {} exiting", id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ impl<K: Kind> VerificationQueue<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let State::Exit = *state.0.lock() {
|
if let State::Exit = *state.0.lock() {
|
||||||
debug!(target: "verification", "verifier {} exiting", id);
|
debug!(target: "verification", "verifier {} exiting", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,8 +687,12 @@ impl<K: Kind> Drop for VerificationQueue<K> {
|
|||||||
*self.state.0.lock() = State::Exit;
|
*self.state.0.lock() = State::Exit;
|
||||||
self.state.1.notify_all();
|
self.state.1.notify_all();
|
||||||
|
|
||||||
// wake up all threads waiting for more work.
|
// acquire this lock to force threads to reach the waiting point
|
||||||
self.more_to_verify.notify_all();
|
// if they're in-between the exit check and the more_to_verify wait.
|
||||||
|
{
|
||||||
|
let _more = self.verification.more_to_verify.lock().unwrap();
|
||||||
|
self.more_to_verify.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
// wait for all verifier threads to join.
|
// wait for all verifier threads to join.
|
||||||
for thread in self.verifier_handles.drain(..) {
|
for thread in self.verifier_handles.drain(..) {
|
||||||
@ -817,7 +821,7 @@ mod tests {
|
|||||||
fn readjust_verifiers() {
|
fn readjust_verifiers() {
|
||||||
let queue = get_test_queue(true);
|
let queue = get_test_queue(true);
|
||||||
|
|
||||||
// put all the verifiers to sleep to ensure
|
// put all the verifiers to sleep to ensure
|
||||||
// the test isn't timing sensitive.
|
// the test isn't timing sensitive.
|
||||||
*queue.state.0.lock() = State::Work(0);
|
*queue.state.0.lock() = State::Work(0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user