x86: sends the EOI later in the IRQ path
[akaros.git] / kern / src / vfs.c
index 4c91522..7b4c298 100644 (file)
@@ -1750,6 +1750,13 @@ ssize_t pipe_file_write(struct file *file, const char *buf, size_t count,
                }
                cv_wait(&pii->p_cv);
                cpu_relax();
+               /* Still need to check in the loop, in case the last reader left while
+                * we slept. */
+               if (!pii->p_nr_readers) {
+                       cv_unlock(&pii->p_cv);
+                       set_errno(EPIPE);
+                       return -1;
+               }
        }
        /* We might need to wrap-around with our copy, so we'll do the copy in two
         * passes.  This will copy up to the end of the buffer, then on the next
@@ -1803,6 +1810,8 @@ int pipe_release(struct inode *inode, struct file *file)
        } else {
                warn("Bad pipe file flags 0x%x\n", file->f_flags);
        }
+       /* need to wake up any sleeping readers/writers, since we might be done */
+       __cv_broadcast(&pii->p_cv);
        cv_unlock(&pii->p_cv);
        return 0;
 }
@@ -1815,6 +1824,19 @@ struct file_operations pipe_f_op = {
        0
 };
 
+void pipe_debug(struct file *f)
+{
+       struct pipe_inode_info *pii = f->f_dentry->d_inode->i_pipe;
+       assert(pii);
+       printk("PIPE %p\n", pii);
+       printk("\trdoff %p\n", pii->p_rd_off);
+       printk("\twroff %p\n", pii->p_wr_off);
+       printk("\tnr_rds %d\n", pii->p_nr_readers);
+       printk("\tnr_wrs %d\n", pii->p_nr_writers);
+       printk("\tcv waiters %d\n", pii->p_cv.nr_waiters);
+
+}
+
 /* General plan: get a dentry/inode to represent the pipe.  We'll alloc it from
  * the default_ns SB, but won't actually link it anywhere.  It'll only be held
  * alive by the krefs, til all the FDs are closed. */