예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
    }
}
예제 #4
0
파일: pipe.c 프로젝트: SnkBitten/amithlon4
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);
}
예제 #5
0
파일: imfs_fifo.c 프로젝트: zhongweiy/rtems
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);
}
예제 #6
0
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);
}
예제 #7
0
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);
}
예제 #8
0
// 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);
}
예제 #9
0
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);
}
예제 #10
0
/*
 * 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;
}
예제 #11
0
파일: pipe.c 프로젝트: SnkBitten/amithlon4
static int
pipe_write_release(struct inode *inode, struct file *filp)
{
	return pipe_release(inode, 0, 1);
}
예제 #12
0
파일: pipe.c 프로젝트: SnkBitten/amithlon4
static int
pipe_read_release(struct inode *inode, struct file *filp)
{
	return pipe_release(inode, 1, 0);
}
예제 #13
0
static int
pipe_write_release(struct inode *inode, struct file *filp)
{
    pipe_write_fasync(-1, filp, 0);
    return pipe_release(inode, 0, 1);
}
예제 #14
0
static int
pipe_read_release(struct inode *inode, struct file *filp)
{
    pipe_read_fasync(-1, filp, 0);
    return pipe_release(inode, 1, 0);
}
예제 #15
0
static int pipe_write_release(struct inode * inode, struct file * filp)
{
	PIPE_WRITERS(*inode)--;
	return pipe_release(inode);
}
예제 #16
0
static int pipe_read_release(struct inode * inode, struct file * filp)
{
	PIPE_READERS(*inode)--;
	return pipe_release(inode);
}