diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index 3967e41..e373a1d 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -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); + } } } } diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index b905fde..4dc9435 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -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); } } diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index a03f107..61db073 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -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>, SpinNoIrq> { + fn add_to_wait_queue(&self) -> MutexGuard>, 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; - drop(guard); - self._wait(); + let lock = self.add_to_wait_queue(); + thread::park_action(move || { + drop(lock); + drop(guard); + }); mutex.lock() } @@ -80,7 +86,4 @@ impl Condvar { } count } - pub fn _clear(&self) { - self.wait_queue.lock().clear(); - } } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index e7f867c..54c7925 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -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) } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 9fcb97e..b24c960 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -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); } }