static void channel_transfer (channel_t *src) { src->flags &= ~FLAG_ACTIVITY; pipe_t *p; if (!(p = src->peer->tosend)) p = pipe_init(); src->peer->tosend = NULL; int rc = splice(src->sock, 0, p->fd[1], 0, PIPE_SIZE, SPLICE_F_MOVE|SPLICE_F_MORE|SPLICE_F_NONBLOCK); if (rc == 0) { src->events &= ~EPOLLIN; src->flags |= FLAG_SHUT_RECV; } else if (rc < 0) { src->events &= ~EPOLLIN; if (errno != EAGAIN) src->flags |= FLAG_ERRONEOUS; } else { p->load += rc; } if (p->load <= 0) return pipe_release(&p); src->peer->tosend = p; return _pipe_resume(src->peer); }
static int pipe_rdwr_release(struct inode * inode, struct file * filp) { if (filp->f_mode & FMODE_READ) PIPE_READERS(*inode)--; if (filp->f_mode & FMODE_WRITE) PIPE_WRITERS(*inode)--; return pipe_release(inode); }
static void channel_patch (channel_t *c) { if (c->flags & FLAG_SHUT_RECV) { c->events &= ~EPOLLIN; channel_shut(c->peer); if (c->tosend) pipe_release(&c->tosend); } }
static int pipe_rdwr_release(struct inode *inode, struct file *filp) { int decr, decw; decr = (filp->f_mode & FMODE_READ) != 0; decw = (filp->f_mode & FMODE_WRITE) != 0; return pipe_release(inode, decr, decw); }
static int IMFS_fifo_close( rtems_libio_t *iop ) { int err = 0; IMFS_jnode_t *jnode = iop->pathinfo.node_access; pipe_release(&JNODE2PIPE(jnode), iop); IMFS_FIFO_RETURN(err); }
static void channel_shut (channel_t *chan) { if (chan->flags & FLAG_SHUT_SENT) return; if (chan->tosend) return; chan->flags |= FLAG_SHUT_SENT; shutdown(chan->sock, SHUT_WR); chan->events &= ~EPOLLOUT; pipe_release(&chan->tosend); }
static void channel_close (channel_t *chan) { if (chan->sock < 0) return; if (ISMONITORED(chan)) -- count_epoll; close(chan->sock); chan->sock = -1; chan->flags = chan->events = 0; pipe_release(&chan->tosend); }
// Return a boolean value, FALSE if an error occured, TRUE if no socket // error was met. static void _pipe_resume (channel_t *chan) { pipe_t *p = chan->tosend; chan->tosend = NULL; while (p->load) { int rc = splice(p->fd[0], 0, chan->sock, 0, p->load, SPLICE_F_MOVE|SPLICE_F_MORE|SPLICE_F_NONBLOCK); if (rc < 0) { chan->events &= ~EPOLLOUT; if (errno == EAGAIN) chan->tosend = p; else { chan->flags |= FLAG_ERRONEOUS; pipe_release(&p); } return; } p->load -= rc; } pipe_release(&p); }
int IMFS_fifo_close( epos_libio_t *iop ) { IMFS_jnode_t *jnode = iop->file_info; int err = pipe_release(&JNODE2PIPE(jnode), iop); if (! err) { iop->flags &= ~LIBIO_FLAGS_OPEN; /* Free jnode if file is already unlinked and no one opens it */ if (! epos_libio_is_file_open(jnode) && jnode->st_nlink < 1) free(jnode); } IMFS_FIFO_RETURN(err); }
/* * Interface to file system open. * * *pipep points to pipe control structure. If called with *pipep = NULL, * fifo_open will try allocating and initializing a control structure. If the * call succeeds, *pipep will be set to address of new control structure. */ int fifo_open( pipe_control_t **pipep, rtems_libio_t *iop ) { pipe_control_t *pipe; unsigned int prevCounter; int err; err = pipe_new(pipep); if (err) return err; pipe = *pipep; switch (LIBIO_ACCMODE(iop)) { case LIBIO_FLAGS_READ: pipe->readerCounter ++; if (pipe->Readers ++ == 0) PIPE_WAKEUPWRITERS(pipe); if (pipe->Writers == 0) { /* Not an error */ if (LIBIO_NODELAY(iop)) break; prevCounter = pipe->writerCounter; err = -EINTR; /* Wait until a writer opens the pipe */ do { PIPE_UNLOCK(pipe); if (! PIPE_READWAIT(pipe)) goto out_error; if (! PIPE_LOCK(pipe)) goto out_error; } while (prevCounter == pipe->writerCounter); } break; case LIBIO_FLAGS_WRITE: pipe->writerCounter ++; if (pipe->Writers ++ == 0) PIPE_WAKEUPREADERS(pipe); if (pipe->Readers == 0 && LIBIO_NODELAY(iop)) { PIPE_UNLOCK(pipe); err = -ENXIO; goto out_error; } if (pipe->Readers == 0) { prevCounter = pipe->readerCounter; err = -EINTR; do { PIPE_UNLOCK(pipe); if (! PIPE_WRITEWAIT(pipe)) goto out_error; if (! PIPE_LOCK(pipe)) goto out_error; } while (prevCounter == pipe->readerCounter); } break; case LIBIO_FLAGS_READ_WRITE: pipe->readerCounter ++; if (pipe->Readers ++ == 0) PIPE_WAKEUPWRITERS(pipe); pipe->writerCounter ++; if (pipe->Writers ++ == 0) PIPE_WAKEUPREADERS(pipe); break; } PIPE_UNLOCK(pipe); return 0; out_error: pipe_release(pipep, iop); return err; }
static int pipe_write_release(struct inode *inode, struct file *filp) { return pipe_release(inode, 0, 1); }
static int pipe_read_release(struct inode *inode, struct file *filp) { return pipe_release(inode, 1, 0); }
static int pipe_write_release(struct inode *inode, struct file *filp) { pipe_write_fasync(-1, filp, 0); return pipe_release(inode, 0, 1); }
static int pipe_read_release(struct inode *inode, struct file *filp) { pipe_read_fasync(-1, filp, 0); return pipe_release(inode, 1, 0); }
static int pipe_write_release(struct inode * inode, struct file * filp) { PIPE_WRITERS(*inode)--; return pipe_release(inode); }
static int pipe_read_release(struct inode * inode, struct file * filp) { PIPE_READERS(*inode)--; return pipe_release(inode); }