note potential lost wakeup problem in Condvar. fix some use case.

toolchain_update
WangRunji 6 years ago
parent 8651f09b31
commit 6c988c4bfd

@ -30,10 +30,12 @@ impl Stdin {
}
#[cfg(not(feature = "board_k210"))]
loop {
let ret = self.buf.lock().pop_front();
match ret {
let mut buf_lock = self.buf.lock();
match buf_lock.pop_front() {
Some(c) => return c,
None => self.pushed._wait(),
None => {
self.pushed.wait(buf_lock);
}
}
}
}

@ -265,9 +265,8 @@ impl Socket for TcpSocketState {
TcpState::SynSent => {
// still connecting
drop(socket);
drop(sockets);
debug!("poll for connection wait");
SOCKET_ACTIVITY._wait();
SOCKET_ACTIVITY.wait(sockets);
}
TcpState::Established => {
break Ok(0);
@ -357,10 +356,8 @@ impl Socket for TcpSocketState {
return Ok((new_socket, Endpoint::Ip(remote_endpoint)));
}
// avoid deadlock
drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait();
SOCKET_ACTIVITY.wait(sockets);
}
}
@ -447,9 +444,8 @@ impl Socket for UdpSocketState {
);
}
// avoid deadlock
drop(socket);
SOCKET_ACTIVITY._wait()
SOCKET_ACTIVITY.wait(sockets);
}
}
@ -626,10 +622,8 @@ impl Socket for RawSocketState {
);
}
// avoid deadlock
drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait()
SOCKET_ACTIVITY.wait(sockets);
}
}

@ -15,6 +15,7 @@ impl Condvar {
}
/// Park current thread and wait for this condvar to be notified.
#[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")]
pub fn _wait(&self) {
// The condvar might be notified between adding to queue and thread parking.
// So park current thread before wait queue lock is freed.
@ -25,6 +26,7 @@ impl Condvar {
});
}
#[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")]
pub fn wait_any(condvars: &[&Condvar]) {
let token = Arc::new(thread::current());
// Avoid racing in the same way as the function above
@ -40,19 +42,23 @@ impl Condvar {
});
}
pub fn add_to_wait_queue(&self) -> MutexGuard<VecDeque<Arc<thread::Thread>>, SpinNoIrq> {
fn add_to_wait_queue(&self) -> MutexGuard<VecDeque<Arc<thread::Thread>>, SpinNoIrq> {
let mut lock = self.wait_queue.lock();
lock.push_back(Arc::new(thread::current()));
return lock;
}
/// Park current thread and wait for this condvar to be notified.
pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S>
where
S: MutexSupport,
{
let mutex = guard.mutex;
let lock = self.add_to_wait_queue();
thread::park_action(move || {
drop(lock);
drop(guard);
self._wait();
});
mutex.lock()
}
@ -80,7 +86,4 @@ impl Condvar {
}
count
}
pub fn _clear(&self) {
self.wait_queue.lock().clear();
}
}

@ -91,6 +91,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
return Err(SysError::EAGAIN);
}
// FIXME: support timeout
// FIXME: fix racing
queue._wait();
Ok(0)
}

@ -120,8 +120,7 @@ pub fn sys_wait4(pid: isize, wstatus: *mut i32) -> SysResult {
target
);
let condvar = proc.child_exit.clone();
drop(proc); // must release lock of current process
condvar._wait();
condvar.wait(proc);
}
}

Loading…
Cancel
Save