need to integrate this into the I/O loop, but when we do it changes
how we handle the psleep_flags bit. Pipes wrap before 64k so we can
shorten the check */
-static uint8_t pipewait(inoptr ino, uint8_t flag)
+static uint8_t wait_pipe_read(inoptr ino, uint8_t flag)
{
while((uint16_t)ino->c_node.i_size == 0) {
if (ino->c_writers == 0 || psleep_flags(ino, flag)) {
return 1;
}
+/* Wait for our pipe to become writable. We must have enough space and
+ a reader */
+static uint8_t wait_pipe_write(inoptr ino, uint8_t flag)
+{
+ while (LOWORD(ino->c_node.i_size) > 8 * BLKSIZE) {
+ if (ino->c_readers == 0) { /* No readers */
+ udata.u_done = (usize_t)-1;
+ udata.u_error = EPIPE;
+ ssig(udata.u_ptab, SIGPIPE);
+ return 1;
+ }
+ /* Sleep if pipe full */
+ if (psleep_flags(ino, flag))
+ return 1;
+ }
+ return 0;
+}
/* We need this because SDCC otherwise makes a right hash of it */
static uint16_t uoff(void)
{
case MODE_R(F_PIPE):
ispipe = true;
/* This bit really needs to be inside the loop for pipe cases */
- if (!pipewait(ino, flag))
+ if (!wait_pipe_read(ino, flag))
break;
goto loop;
}
}
-
-
void writei(regptr inoptr ino, uint8_t flag)
{
usize_t amount;
#endif
case MODE_R(F_PIPE):
ispipe = true;
- /* FIXME: this will hang if you ever write > 16 * BLKSIZE
- in one go - needs merging into the loop */
- while (udata.u_count > (16 * BLKSIZE) -
- LOWORD(ino->c_node.i_size)) {
- if (ino->c_readers == 0) { /* No readers */
- udata.u_done = (usize_t)-1;
- udata.u_error = EPIPE;
- ssig(udata.u_ptab, SIGPIPE);
- return;
- }
- /* Sleep if empty pipe */
- if (psleep_flags(ino, flag))
- return;
- }
- /* Sleep if empty pipe */
case MODE_R(F_DIR):
case MODE_R(F_REG):
flag = flag & O_SYNC ? 2 : 1;
while (udata.u_count) {
+ if (ispipe) {
+ /* Sleep if empty pipe */
+ if (wait_pipe_write(ino, flag))
+ return;
+ }
pblk = mapcalc(ino, &amount, 0);
if (HIBYTE32(udata.u_offset) & BLKOVERSIZE32) {