diff --git a/async/src/async_door.rs b/async/src/async_door.rs
index 13ae34204fe448e5105ac26c38b03260defe09ca..4507053d2a73bddb91f3a3e0b6ae07ce7148bab0 100644
--- a/async/src/async_door.rs
+++ b/async/src/async_door.rs
@@ -404,13 +404,17 @@ fn chan_poll_write<'a>(
     trace!("chan write");
 
     let mut p = poll_lock(door.inner.clone(), cx, lock_fut);
-    let runner = match p {
-        Poll::Ready(ref mut i) => &mut i.runner,
+    let inner = match p {
+        Poll::Ready(ref mut i) => i,
         Poll::Pending => return Poll::Pending,
     };
+    let runner = &mut inner.runner;
 
     match runner.channel_send(chan, ext, buf) {
-        Ok(Some(l)) if l == 0 => Poll::Pending,
+        Ok(Some(l)) if l == 0 => {
+            inner.chan_write_wakers.insert((chan, ext), cx.waker().clone());
+            Poll::Pending
+        }
         Ok(Some(l)) => Poll::Ready(Ok(l)),
         // return 0 for EOF
         Ok(None) => Poll::Ready(Ok(0)),
diff --git a/sshproto/src/channel.rs b/sshproto/src/channel.rs
index 8e50793776a6b143ee337f44f82a8ed3ac6a8fbf..d86fdeb894e0dbca38a324aa857d7bb6d5645d55 100644
--- a/sshproto/src/channel.rs
+++ b/sshproto/src/channel.rs
@@ -439,6 +439,7 @@ impl Channel {
         let send = self.send.as_mut().trap()?;
         if self.pending_adjust > self.full_window / 2 {
             let adjust = self.pending_adjust as u32;
+            self.pending_adjust = 0;
             let p = packets::ChannelWindowAdjust { num: send.num, adjust }.into();
             Ok(Some(p))
         } else {
diff --git a/sshproto/src/runner.rs b/sshproto/src/runner.rs
index cff34740881d4a380078e31650375aaa61e73ea2..01358315f05f59e15a3181d4d8a433afc5a4e8d0 100644
--- a/sshproto/src/runner.rs
+++ b/sshproto/src/runner.rs
@@ -183,6 +183,7 @@ impl<'a> Runner<'a> {
     ) -> Result<Option<usize>> {
         let len = self.ready_channel_send(chan);
         let len = match len {
+            Some(l) if l == 0 => return Ok(Some(0)),
             Some(l) => l,
             None => return Ok(None),
         };