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"))] #[cfg(not(feature = "board_k210"))]
loop { loop {
let ret = self.buf.lock().pop_front(); let mut buf_lock = self.buf.lock();
match ret { match buf_lock.pop_front() {
Some(c) => return c, Some(c) => return c,
None => self.pushed._wait(), None => {
self.pushed.wait(buf_lock);
}
} }
} }
} }

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

@ -15,6 +15,7 @@ impl Condvar {
} }
/// Park current thread and wait for this condvar to be notified. /// 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) { pub fn _wait(&self) {
// The condvar might be notified between adding to queue and thread parking. // The condvar might be notified between adding to queue and thread parking.
// So park current thread before wait queue lock is freed. // 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]) { pub fn wait_any(condvars: &[&Condvar]) {
let token = Arc::new(thread::current()); let token = Arc::new(thread::current());
// Avoid racing in the same way as the function above // 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(); let mut lock = self.wait_queue.lock();
lock.push_back(Arc::new(thread::current())); lock.push_back(Arc::new(thread::current()));
return lock; 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> pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S>
where where
S: MutexSupport, S: MutexSupport,
{ {
let mutex = guard.mutex; let mutex = guard.mutex;
drop(guard); let lock = self.add_to_wait_queue();
self._wait(); thread::park_action(move || {
drop(lock);
drop(guard);
});
mutex.lock() mutex.lock()
} }
@ -80,7 +86,4 @@ impl Condvar {
} }
count 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); return Err(SysError::EAGAIN);
} }
// FIXME: support timeout // FIXME: support timeout
// FIXME: fix racing
queue._wait(); queue._wait();
Ok(0) Ok(0)
} }

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

Loading…
Cancel
Save