Esempio n. 1
0
dt_env_t *
dt_create(uint16_t port, uint8_t num_workers)
{
	log_assert(port > 0);
	log_assert(num_workers > 0);

	dt_env_t *env = (dt_env_t *) malloc(sizeof(dt_env_t));
	if (!env) return NULL;

	// Flags. Initial valuse are set here, and each is set again, only once,
	// from another function, possibly in another thread; otherwise,
	// they're only ever read.
	env->so_connected = malloc(sizeof(uint8_t));
	env->dt_stopping = malloc(sizeof(uint8_t));

	*(env->so_connected) = 0;
	*(env->dt_stopping) = 0;

	env->so_pipe = pipe_new(sizeof(void *), 0);

	// These are used in the dt_worker therad. Unbound workers
	// create their own producers
	env->so_consumer = pipe_consumer_new(env->so_pipe);
	env->so_producer = pipe_producer_new(env->so_pipe);
	pthread_create(&env->dt_worker, NULL, __dt_worker, env);

	return env;
}
Esempio n. 2
0
File: tcp4.c Progetto: fd/telehash-c
// internal, get or create a pipe
pipe_t tcp4_pipe(net_tcp4_t net, char *ip, int port)
{
  pipe_t pipe;
  pipe_tcp4_t to;
  char id[23];

  snprintf(id,23,"%s:%d",ip,port);
  pipe = xht_get(net->pipes,id);
  if(pipe) return pipe;

  LOG("new pipe to %s",id);

  // create new tcp4 pipe
  if(!(pipe = pipe_new("tcp4"))) return NULL;
  if(!(pipe->arg = to = malloc(sizeof (struct pipe_tcp4_struct)))) return pipe_free(pipe);
  memset(to,0,sizeof (struct pipe_tcp4_struct));
  to->net = net;
  to->sa.sin_family = AF_INET;
  inet_aton(ip, &(to->sa.sin_addr));
  to->sa.sin_port = htons(port);
  if(!(to->chunks = chunks_new(0))) return tcp4_free(pipe);

  // set up pipe
  pipe->id = strdup(id);
  xht_set(net->pipes,pipe->id,pipe);
  pipe->send = tcp4_send;

  return pipe;
}
Esempio n. 3
0
static pipeline_t va_pipe_pipeline(pipeline_t result_so_far,
                                   va_list args)
{
    pipe_processor_t proc = va_arg(args, pipe_processor_t);

    if(proc == NULL)
        return result_so_far;

    void*  aux       = va_arg(args, void*);
    size_t pipe_size = va_arg(args, size_t);

    if(pipe_size == 0)
    {
        pipe_consumer_free(result_so_far.out);
        result_so_far.out = NULL;
        return result_so_far;
    }

    pipe_t* pipe = pipe_new(pipe_size, 0);

    pipe_connect(result_so_far.out , proc, aux, pipe_producer_new(pipe));
    result_so_far.out = pipe_consumer_new(pipe);

    pipe_free(pipe);

    return va_pipe_pipeline(result_so_far, args);
}
Esempio n. 4
0
static struct inode * get_pipe_inode(void)
{
	struct inode *inode = new_inode(pipe_mnt->mnt_sb);

	if (!inode)
		goto fail_inode;

	if(!pipe_new(inode))
		goto fail_iput;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
	inode->i_fop = &rdwr_pipe_fops;

	/*
	 * Mark the inode dirty from the very beginning,
	 * that way it will never be moved to the dirty
	 * list because "mark_inode_dirty()" will think
	 * that it already _is_ on the dirty list.
	 */
	inode->i_state = I_DIRTY;
	inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
	inode->i_uid = current->fsuid;
	inode->i_gid = current->fsgid;
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	inode->i_blksize = PAGE_SIZE;
	return inode;

fail_iput:
	iput(inode);
fail_inode:
	return NULL;
}
Esempio n. 5
0
static void
server_process_cluster_command (
    server_t *self,
    const char *peer_id,
    const char *peer_name,
    zmsg_t *msg,
    bool unicast)
{
    char *request = zmsg_popstr (msg);
    char *pipename = zmsg_popstr (msg);
    zsys_info ("peer=%s command=%s pipe=%s unicast=%d",
                peer_name, request, pipename? pipename: "-", unicast);

    //  Lookup or create pipe
    //  TODO: remote pipes need cleaning up with some timeout
    pipe_t *pipe = NULL;
    if (pipename) {
        pipe = (pipe_t *) zhash_lookup (self->pipes, pipename);
        if (!pipe)
            pipe = pipe_new (self, pipename);
    }
    if (pipe && streq (request, "HAVE WRITER"))
        pipe_attach_remote_writer (pipe, peer_id, unicast);
    else
    if (pipe && streq (request, "HAVE READER"))
        pipe_attach_remote_reader (pipe, peer_id, unicast);
    else
    if (pipe && streq (request, "DATA")) {
        //  TODO encode these commands as proper protocol
        zframe_t *frame = zmsg_pop (msg);
        zchunk_t *chunk = zchunk_new (zframe_data (frame), zframe_size (frame));
        if (pipe->writer == REMOTE_NODE && pipe->reader) {
            zsys_info ("send %d bytes to pipe", (int) zchunk_size (chunk));
            pipe_send_data (pipe, &chunk); 
        }
        else
            zsys_info ("discard %d bytes, unroutable", (int) zchunk_size (chunk));
            
        zframe_destroy (&frame);
        zchunk_destroy (&chunk);
    }
    else
    if (pipe && streq (request, "DROP READER"))
        pipe_drop_remote_reader (&pipe, peer_id);
    else
    if (pipe && streq (request, "DROP WRITER"))
        pipe_drop_remote_writer (&pipe, peer_id);
    else
    if (streq (request, "DUMP"))
        zyre_dump (self->zyre);
    else
        zsys_warning ("bad request %s from %s", request, peer_name);

    zstr_free (&pipename);
    zstr_free (&request);
}
Esempio n. 6
0
struct robject *pipe_file_cons(rp_t source, int argc, char **argv) {
	struct robject *new_r;
	struct pipe *pipe;

	new_r = rdi_file_cons(robject_new_index(), ACCS_READ | ACCS_WRITE);
	pipe = pipe_new();
	robject_set_data(new_r, "pipe", pipe);

	return new_r;
}
Esempio n. 7
0
static void
lookup_or_create_pipe (client_t *self)
{
    const char *pipename = zpipes_msg_pipename (self->request);
    self->pipe = (pipe_t *) zhash_lookup (self->server->pipes, pipename);
    if (!self->pipe)
        self->pipe = pipe_new (self->server, pipename);

    //  Put pipename into logs for this client
    engine_set_log_prefix (self, pipename);
}
Esempio n. 8
0
File: pipe.c Progetto: pras710/qemu
static Pipe*
pipe_load( PipeDevice* dev, QEMUFile* file, int version_id )
{
    Pipe*              pipe;
    const PipeService* service = NULL;
    int   state = qemu_get_byte(file);
    uint64_t channel;

    if (state != 0) {
        /* Pipe is associated with a service. */
        char* name = qemu_get_string(file);
        if (name == NULL)
            return NULL;

        service = goldfish_pipe_find_type(name);
        if (service == NULL) {
            D("No QEMU pipe service named '%s'", name);
            AFREE(name);
            return NULL;
        }
    }

    if (version_id == GOLDFISH_PIPE_SAVE_VERSION_LEGACY) {
        channel = qemu_get_be32(file);
    } else {
        channel = qemu_get_be64(file);
    }
    pipe = pipe_new(channel, dev);
    pipe->wanted  = qemu_get_byte(file);
    pipe->closed  = qemu_get_byte(file);
    if (qemu_get_byte(file) != 0) {
        pipe->args = qemu_get_string(file);
    }

    pipe->service = service;
    if (service != NULL) {
        pipe->funcs = &service->funcs;
    }

    if (pipe->funcs->load) {
        pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
        if (pipe->opaque == NULL) {
            AFREE(pipe);
            return NULL;
        }
    } else {
        /* Force-close the pipe on load */
        pipe->closed = 1;
    }
    return pipe;
}
Esempio n. 9
0
File: io.c Progetto: yubo/bird
void
pipe_drain(int fd)
{
  char buf[64];
  int rv;
  
 try:
  rv = read(fd, buf, 64);
  if (rv < 0)
  {
    if (errno == EINTR)
      goto try;
    if (errno == EAGAIN)
      return;
    die("wakeup read: %m");
  }
  if (rv == 64)
    goto try;
}

void
pipe_kick(int fd)
{
  u64 v = 1;
  int rv;

 try:
  rv = write(fd, &v, sizeof(u64));
  if (rv < 0)
  {
    if (errno == EINTR)
      goto try;
    if (errno == EAGAIN)
      return;
    die("wakeup write: %m");
  }
}

static inline void
wakeup_init(struct birdloop *loop)
{
  pipe_new(loop->wakeup_fds);
}

static inline void
wakeup_drain(struct birdloop *loop)
{
  pipe_drain(loop->wakeup_fds[0]);
}
Esempio n. 10
0
pipeline_t pipe_parallel(size_t           instances,
                         size_t           in_size,
                         pipe_processor_t proc,
                         void*            aux,
                         size_t           out_size)
{
    pipe_t* in  = pipe_new(in_size,  0),
          * out = pipe_new(out_size, 0);

    while(instances--)
        pipe_connect(pipe_consumer_new(in),
                     proc, aux,
                     pipe_producer_new(out));

    pipeline_t ret = {
        .in  = pipe_producer_new(in),
        .out = pipe_consumer_new(out)
    };

    pipe_free(in);
    pipe_free(out);

    return ret;
}
Esempio n. 11
0
pipeline_t pipe_pipeline(size_t first_size, ...)
{
    va_list va;
    va_start(va, first_size);

    pipe_t* p = pipe_new(first_size, 0);

    pipeline_t ret = va_pipe_pipeline(pipe_trivial_pipeline(p), va);

    pipe_free(p);

    va_end(va);

    return ret;
}
Esempio n. 12
0
static Pipe*
pipe_load( PipeDevice* dev, QEMUFile* file )
{
    Pipe*              pipe;
    const PipeService* service = NULL;
    int   state = qemu_get_byte(file);
    uint32_t channel;

    if (state != 0) {
        
        char* name = qemu_get_string(file);
        if (name == NULL)
            return NULL;

        service = goldfish_pipe_find_type(name);
        if (service == NULL) {
            D("No QEMU pipe service named '%s'", name);
            AFREE(name);
            return NULL;
        }
    }

    channel = qemu_get_be32(file);
    pipe = pipe_new(channel, dev);
    pipe->wanted  = qemu_get_byte(file);
    pipe->closed  = qemu_get_byte(file);
    if (qemu_get_byte(file) != 0) {
        pipe->args = qemu_get_string(file);
    }

    pipe->service = service;
    if (service != NULL) {
        pipe->funcs = &service->funcs;
    }

    if (pipe->funcs->load) {
        pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
        if (pipe->opaque == NULL) {
            AFREE(pipe);
            return NULL;
        }
    } else {
        
        pipe->closed = 1;
    }
    return pipe;
}
Esempio n. 13
0
net_loopback_t net_loopback_new(mesh_t a, mesh_t b)
{
  net_loopback_t pair;

  if(!(pair = malloc(sizeof (struct net_loopback_struct)))) return LOG("OOM");
  memset(pair,0,sizeof (struct net_loopback_struct));
  if(!(pair->pipe = pipe_new("pair")))
  {
    free(pair);
    return LOG("OOM");
  }
  pair->a = a;
  pair->b = b;
  pair->pipe->id = strdup("loopback");
  pair->pipe->arg = pair;
  pair->pipe->send = pair_send;

  // ensure they're linked and piped together
  link_pipe(link_keys(a,b->keys),pair->pipe);
  link_pipe(link_keys(b,a->keys),pair->pipe);

  return pair;
}
Esempio n. 14
0
pipe_t net_serial_add(net_serial_t net, const char *name, int (*read)(void), int (*write)(uint8_t *buf, size_t len), uint8_t buffer)
{
  pipe_t pipe;
  pipe_serial_t to;

  // just sanity checks
  if(!net || !name || !read || !write) return NULL;

  pipe = xht_get(net->pipes, name);
  if(!pipe)
  {
    if(!(pipe = pipe_new("serial"))) return NULL;
    if(!(pipe->arg = to = malloc(sizeof (struct pipe_serial_struct)))) return pipe_free(pipe);
    memset(to,0,sizeof (struct pipe_serial_struct));
    to->net = net;
    if(!(to->chunks = util_chunks_new(buffer)))
    {
      free(to);
      return pipe_free(pipe);
    }

    // set up pipe
    pipe->id = strdup(name);
    xht_set(net->pipes,pipe->id,pipe);
    pipe->send = serial_send;
    
  }else{
    if(!(to = (pipe_serial_t)pipe->arg)) return NULL;
  }

  // these can be modified
  to->read = read;
  to->write = write;

  return pipe;
}
Esempio n. 15
0
static void
pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
{
    Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
    Pipe*  pipe   = *lookup;
    CPUState* env = cpu_single_env;

    
    if (command != PIPE_CMD_OPEN && pipe == NULL) {
        dev->status = PIPE_ERROR_INVAL;
        return;
    }

    
    if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
        dev->status = PIPE_ERROR_IO;
        return;
    }

    switch (command) {
    case PIPE_CMD_OPEN:
        DD("%s: CMD_OPEN channel=0x%x", __FUNCTION__, dev->channel);
        if (pipe != NULL) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        pipe = pipe_new(dev->channel, dev);
        pipe->next = dev->pipes;
        dev->pipes = pipe;
        dev->status = 0;
        break;

    case PIPE_CMD_CLOSE:
        DD("%s: CMD_CLOSE channel=0x%x", __FUNCTION__, dev->channel);
        
        *lookup = pipe->next;
        pipe->next = NULL;
        pipe_list_remove_waked(&dev->signaled_pipes, pipe);
        pipe_free(pipe);
        break;

    case PIPE_CMD_POLL:
        dev->status = pipe->funcs->poll(pipe->opaque);
        DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
        break;

    case PIPE_CMD_READ_BUFFER: {
        
        GoldfishPipeBuffer  buffer;
        uint32_t            address = dev->address;
        uint32_t            page    = address & TARGET_PAGE_MASK;
        target_phys_addr_t  phys;
        phys = safe_get_phys_page_debug(env, page);
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
        DD("%s: CMD_READ_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
           __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WRITE_BUFFER: {
        
        GoldfishPipeBuffer  buffer;
        uint32_t            address = dev->address;
        uint32_t            page    = address & TARGET_PAGE_MASK;
        target_phys_addr_t  phys;
        phys = safe_get_phys_page_debug(env, page);
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
        DD("%s: CMD_WRITE_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
           __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WAKE_ON_READ:
        DD("%s: CMD_WAKE_ON_READ channel=0x%x", __FUNCTION__, dev->channel);
        if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
            pipe->wanted |= PIPE_WAKE_READ;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    case PIPE_CMD_WAKE_ON_WRITE:
        DD("%s: CMD_WAKE_ON_WRITE channel=0x%x", __FUNCTION__, dev->channel);
        if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
            pipe->wanted |= PIPE_WAKE_WRITE;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    default:
        D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
    }
}
Esempio n. 16
0
static int fifo_open(struct inode *inode, struct file *filp)
{
	int ret;

	ret = -ERESTARTSYS;
	lock_kernel();
	if (down_interruptible(PIPE_SEM(*inode)))
		goto err_nolock_nocleanup;

	if (!inode->i_pipe) {
		ret = -ENOMEM;
		if(!pipe_new(inode))
			goto err_nocleanup;
	}
	filp->f_version = 0;

	switch (filp->f_mode) {
	case 1:
	/*
	 *  O_RDONLY
	 *  POSIX.1 says that O_NONBLOCK means return with the FIFO
	 *  opened, even when there is no process writing the FIFO.
	 */
		filp->f_op = &read_fifo_fops;
		PIPE_RCOUNTER(*inode)++;
		if (PIPE_READERS(*inode)++ == 0)
			wake_up_partner(inode);

		if (!PIPE_WRITERS(*inode)) {
			if ((filp->f_flags & O_NONBLOCK)) {
				/* suppress POLLHUP until we have
				 * seen a writer */
				filp->f_version = PIPE_WCOUNTER(*inode);
			} else 
			{
				wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
				if(signal_pending(current))
					goto err_rd;
			}
		}
		break;
	
	case 2:
	/*
	 *  O_WRONLY
	 *  POSIX.1 says that O_NONBLOCK means return -1 with
	 *  errno=ENXIO when there is no process reading the FIFO.
	 */
		ret = -ENXIO;
		if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
			goto err;

		filp->f_op = &write_fifo_fops;
		PIPE_WCOUNTER(*inode)++;
		if (!PIPE_WRITERS(*inode)++)
			wake_up_partner(inode);

		if (!PIPE_READERS(*inode)) {
			wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
			if (signal_pending(current))
				goto err_wr;
		}
		break;
	
	case 3:
	/*
	 *  O_RDWR
	 *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
	 *  This implementation will NEVER block on a O_RDWR open, since
	 *  the process can at least talk to itself.
	 */
		filp->f_op = &rdwr_fifo_fops;

		PIPE_READERS(*inode)++;
		PIPE_WRITERS(*inode)++;
		PIPE_RCOUNTER(*inode)++;
		PIPE_WCOUNTER(*inode)++;
		if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
			wake_up_partner(inode);
		break;

	default:
		ret = -EINVAL;
		goto err;
	}

	/* Ok! */
	up(PIPE_SEM(*inode));
	unlock_kernel();
	return 0;

err_rd:
	if (!--PIPE_READERS(*inode))
		wake_up_interruptible(PIPE_WAIT(*inode));
	ret = -ERESTARTSYS;
	goto err;

err_wr:
	if (!--PIPE_WRITERS(*inode))
		wake_up_interruptible(PIPE_WAIT(*inode));
	ret = -ERESTARTSYS;
	goto err;

err:
	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
		struct pipe_inode_info *info = inode->i_pipe;
		inode->i_pipe = NULL;
		free_page((unsigned long)info->base);
		kfree(info);
	}

err_nocleanup:
	up(PIPE_SEM(*inode));

err_nolock_nocleanup:
	unlock_kernel();
	return ret;
}
Esempio n. 17
0
/*
 * create a file reader in the ``INIT'' state
 */
struct wav *
wav_new_in(struct fileops *ops, struct dev *dev,
    unsigned int mode, char *name, unsigned int hdr,
    struct aparams *par, unsigned int xrun,
    unsigned int volctl, int mmc, int join)
{
	int fd;
	struct wav *f;

	if (!wav_autohdr(name, dev, &hdr, &mode))
		return NULL;
	if (strcmp(name, "-") == 0) {
		fd = STDIN_FILENO;
		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
			perror(name);
	} else {
		fd = open(name, O_RDONLY | O_NONBLOCK, 0666);
		if (fd < 0) {
			perror(name);
			return NULL;
		}
	}
	f = (struct wav *)pipe_new(ops, fd, name);
	if (f == NULL) {
		close(fd);
		return NULL;
	}
	f->mode = mode;
	f->pstate = WAV_CFG;
	f->endpos = f->startpos = 0;
	f->next = wav_list;
	wav_list = f;
	if (hdr == HDR_WAV) {
		if (!wav_readhdr(f->pipe.fd, par,
			&f->startpos, &f->rbytes, &f->map)) {
			file_del((struct file *)f);
			return NULL;
		}
		f->endpos = f->startpos + f->rbytes;
	} else {
		f->endpos = pipe_endpos(&f->pipe.file);
		if (f->endpos > 0) {
			if (!pipe_seek(&f->pipe.file, 0)) {
				file_del((struct file *)f);
				return NULL;
			}
			f->rbytes = f->endpos;
		} else
			f->rbytes = -1;
		f->map = NULL;
	}
	f->dev = dev;
	f->mmc = mmc;
	f->join = join;
	f->mode = mode;
	f->hpar = *par;
	f->hdr = hdr;
	f->xrun = xrun;
	f->maxweight = MIDI_TO_ADATA(volctl);
	f->slot = -1;
	rwav_new((struct file *)f);
#ifdef DEBUG
	if (debug_level >= 2) {
		dbg_puts(name);
		dbg_puts(":");
		if (f->mode & MODE_PLAY) {
			dbg_puts(" playing ");
			aparams_dbg(par);
			dbg_puts(" ");
			dbg_putu(f->startpos);
			dbg_puts("..");
			dbg_putu(f->endpos);
			if (f->mmc)
				dbg_puts(", mmc");
		}
		if (f->mode & MODE_MIDIOUT)
			dbg_puts(" midi/out");
		dbg_puts("\n");
	}
#endif
	return f;
}
Esempio n. 18
0
/*
 * create a file writer in the ``INIT'' state
 */
struct wav *
wav_new_out(struct fileops *ops, struct dev *dev,
    unsigned int mode, char *name, unsigned int hdr,
    struct aparams *par, unsigned int xrun, int mmc, int join)
{
	int fd;
	struct wav *f;

	if (!wav_autohdr(name, dev, &hdr, &mode))
		return NULL;
	if (strcmp(name, "-") == 0) {
		fd = STDOUT_FILENO;
		if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
			perror(name);
	} else {
		fd = open(name,
		    O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK, 0666);
		if (fd < 0) {
			perror(name);
			return NULL;
		}
	}
	f = (struct wav *)pipe_new(ops, fd, name);
	if (f == NULL) {
		close(fd);
		return NULL;
	}
	f->mode = mode;
	f->pstate = WAV_CFG;
	f->endpos = f->startpos = 0;
	f->next = wav_list;
	wav_list = f;
	if (hdr == HDR_WAV) {
		par->le = 1;
		par->sig = (par->bits <= 8) ? 0 : 1;
		par->bps = (par->bits + 7) / 8;
		if (!wav_writehdr(f->pipe.fd, par, &f->startpos, 0)) {
			file_del((struct file *)f);
			return NULL;
		}
		f->wbytes = WAV_DATAMAX;
		f->endpos = f->startpos;
	} else
		f->wbytes = -1;
	f->dev = dev;
	f->mmc = mmc;
	f->join = join;
	f->hpar = *par;
	f->hdr = hdr;
	f->xrun = xrun;
	wwav_new((struct file *)f);
#ifdef DEBUG
	if (debug_level >= 2) {
		dbg_puts(name);
		dbg_puts(":");
		if (f->mode & MODE_RECMASK) {
			dbg_puts(" recording ");
			aparams_dbg(par);
			if (f->mmc)
				dbg_puts(", mmc");
		}
		if (f->mode & MODE_MIDIIN)
			dbg_puts(" midi/in");
		dbg_puts("\n");
	}
#endif
	return f;
}
Esempio n. 19
0
File: pipe.c Progetto: pras710/qemu
static void
pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
{
    Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
    Pipe*  pipe   = *lookup;
    CPUOldState* env = cpu_single_env;

    /* Check that we're referring a known pipe channel */
    if (command != PIPE_CMD_OPEN && pipe == NULL) {
        dev->status = PIPE_ERROR_INVAL;
        return;
    }

    /* If the pipe is closed by the host, return an error */
    if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
        dev->status = PIPE_ERROR_IO;
        return;
    }

    switch (command) {
    case PIPE_CMD_OPEN:
        DD("%s: CMD_OPEN channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if (pipe != NULL) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        pipe = pipe_new(dev->channel, dev);
        pipe->next = dev->pipes;
        dev->pipes = pipe;
        dev->status = 0;
        break;

    case PIPE_CMD_CLOSE:
        DD("%s: CMD_CLOSE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        /* Remove from device's lists */
        *lookup = pipe->next;
        pipe->next = NULL;
        pipe_list_remove_waked(&dev->signaled_pipes, pipe);
        pipe_free(pipe);
        break;

    case PIPE_CMD_POLL:
        dev->status = pipe->funcs->poll(pipe->opaque);
        DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
        break;

    case PIPE_CMD_READ_BUFFER: {
        /* Translate virtual address into physical one, into emulator memory. */
        GoldfishPipeBuffer  buffer;
        target_ulong        address = dev->address;
        target_ulong        page    = address & TARGET_PAGE_MASK;
        hwaddr  phys;
        phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page);
#ifdef TARGET_X86_64
        phys = phys & TARGET_PTE_MASK;
#endif
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
		extern int matchMeInPidTid(CPUArchState *);
		extern int getMeContextId(CPUArchState *);
		if(matchMeInPidTid(env))
		{
			printf("%d %s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
				getMeContextId(env),
				__FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
				dev->size, dev->status);
		}
        DD("%s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
           dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WRITE_BUFFER: {
        /* Translate virtual address into physical one, into emulator memory. */
        GoldfishPipeBuffer  buffer;
        target_ulong        address = dev->address;
        target_ulong        page    = address & TARGET_PAGE_MASK;
        hwaddr  phys;
        phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page);
#ifdef TARGET_X86_64
        phys = phys & TARGET_PTE_MASK;
#endif
        buffer.data = qemu_get_ram_ptr(phys) + (address - page);
        buffer.size = dev->size;
        dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
		extern int matchMeInPidTid(CPUArchState *);
		extern int getMeContextId(CPUArchState *);
		if(matchMeInPidTid(env))
		{
	        printf("%d %s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
		       getMeContextId(env),
				__FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
			   dev->size, dev->status);
		}
        DD("%s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
           dev->size, dev->status);
        break;
    }

    case PIPE_CMD_WAKE_ON_READ:
        DD("%s: CMD_WAKE_ON_READ channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
            pipe->wanted |= PIPE_WAKE_READ;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    case PIPE_CMD_WAKE_ON_WRITE:
        DD("%s: CMD_WAKE_ON_WRITE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
            pipe->wanted |= PIPE_WAKE_WRITE;
            pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
        }
        dev->status = 0;
        break;

    default:
        D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
    }
}
Esempio n. 20
0
wtp_handle_t* wtp_alloc(const char* device, wtp_aslan_msg_cb msg_cb)
{
    if ((!device) || (!msg_cb))
	{
        errno = EINVAL;
		return NULL;
    }

    int ret = -1;

    wtp_handle_t *handle = calloc(1, sizeof(wtp_handle_t));
    if (!handle)
	{
        errno = ENOMEM;
		return NULL;
    }

	handle->wtp_state = WTP_STATE_NONE;
    handle->msg_cb = msg_cb;

    //for testing purposes only
    char hds_ip[] = "192.168.1.10";
    handle->hds_port = ASLAN_PROTOCOL_PORT;
    handle->hello_interval_seconds = 5;

    /* UDP socket */
    int s = -1;
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
        free(handle);
		return NULL;
    }
    handle->udp_socket = s;

	if (pthread_mutex_init(&handle->hello_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    if (pthread_mutex_init(&handle->udp_mutex, NULL) != 0)
    {
		free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->ack_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->sta_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

	if (pthread_mutex_init(&handle->monitor_mutex, NULL) != 0)
    {
        free(handle);
		return NULL;
    }

    handle->wtp_sta_hashmap = NULL;

    /* HDS parameters */
    handle->hds_inet_addr.sin_family = AF_INET;
    if (!inet_aton(hds_ip, (struct in_addr*) &(handle->hds_inet_addr.sin_addr.s_addr)))
	{
        errno = EINVAL;
		close_wtp(handle);
		return NULL;
    }
    handle->hds_ip = ntohl(handle->hds_inet_addr.sin_addr.s_addr);

    /* interface name */
    strncpy(handle->device, device, IFNAMSIZ - 1);

    /* interface IP */
    struct ifreq ifr;
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    if (ioctl(handle->udp_socket, SIOCGIFADDR, &ifr) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_ip = ntohl(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr);

    /* HDS sockaddr_in structure */
    handle->hds_inet_addr.sin_addr.s_addr = htonl(handle->hds_ip);
    handle->hds_inet_addr.sin_family  = AF_INET;
    handle->hds_inet_addr.sin_port = htons(handle->hds_port);

    /* UDP socket local port */
    struct sockaddr_in address;
    memset((char*) &address, 0, sizeof(address));
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = 0;
    address.sin_family = AF_INET;
    bind(handle->udp_socket, (struct sockaddr*) &address, sizeof(address));

    struct sockaddr_in sin = {0};
    socklen_t len = sizeof(sin);
    if (getsockname(handle->udp_socket, (struct sockaddr*)&sin, &len) == -1)
	{
		close_wtp(handle);
		return NULL;
    }
    handle->local_port = ntohs(sin.sin_port);
	wpa_printf(MSG_INFO, "INFO: UDP socket for ASLAN messages created, listening on port: %d\n", handle->local_port);

	/* create FIFO pipe producers and consumers */
	pipe_t* recv_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_recv_producer = pipe_producer_new(recv_pipe);
	handle->msg_recv_consumer = pipe_consumer_new(recv_pipe);
	pipe_free(recv_pipe);

	pipe_t* send_pipe = pipe_new(sizeof(aslan_msg_t *), 100);
	handle->msg_send_producer = pipe_producer_new(send_pipe);
	handle->msg_send_consumer = pipe_consumer_new(send_pipe);
	pipe_free(send_pipe);

    /* start receiving thread for ASLAN messages */
    if (pthread_create(&(handle->receive_thread), NULL, receive_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: receiving thread for ASLAN messages created\n");

	/* start processing thread for ASLAN messages */
    if (pthread_create(&(handle->process_thread), NULL, process_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: processing thread for ASLAN messages created\n");

	/* start sending thread for ASLAN messages */
    if (pthread_create(&(handle->send_thread), NULL, send_msg_thread, (void*)handle) != 0)
    {
        errno = ENOMEM;
		close_wtp(handle);
		return NULL;
    }
	wpa_printf(MSG_INFO, "DEBUG: sending thread for ASLAN messages created\n");

    /* obtain HDS MAC address by a Hello message */
    if (wtp_send_hello_msg(handle) == -1)
	{
		close_wtp(handle);
		return NULL;
    }

    /* Check ARP cache */
    if (handle->local_ip != handle->hds_ip)
    {
        struct arpreq areq;
        memset(&areq, 0, sizeof(areq));
        struct sockaddr_in* sockaddr = NULL;
        sockaddr = (struct sockaddr_in*) &(areq.arp_pa);
        sockaddr->sin_family = AF_INET;
        sockaddr->sin_addr.s_addr = htonl(handle->hds_ip);
        sockaddr = (struct sockaddr_in*) &(areq.arp_ha);
        sockaddr->sin_family = ARPHRD_ETHER;
        strncpy(areq.arp_dev, device, IFNAMSIZ - 1);

        int i = 0;
        unsigned char mac_loopback[] = {0, 0, 0, 0, 0, 0};

        ioctl(s, SIOCGARP, (caddr_t) &areq);
        while ((i < 5) && (mac_cmp(areq.arp_ha.sa_data, mac_loopback)))
		{
            i++;
            sleep(1);
            ioctl(s, SIOCGARP, (caddr_t) &areq);
        }

        memcpy(handle->hds_mac, areq.arp_ha.sa_data, 6);

        if (mac_cmp(areq.arp_ha.sa_data, mac_loopback)) wpa_printf(MSG_WARNING, "WARNING: HDS MAC address obtaining failed\n");
        else wpa_printf(MSG_INFO, "INFO: HDS MAC address found: "MACSTR"\n", MAC2STR(handle->hds_mac));
    }
    else wpa_printf(MSG_INFO, "INFO: WTP started at loopback\n");

    return handle;
}
Esempio n. 21
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;
}
Esempio n. 22
0
DWORD
CE_Initialize (
    PCONFIGURATION_ENTRY    pce,
    HANDLE                  hMgrNotificationEvent,
    PSUPPORT_FUNCTIONS      psfSupportFunctions,
    PXORPRTM_GLOBAL_CONFIG pigc)
{
    DWORD   dwErr               = NO_ERROR;
    pipe_instance_t *pp;
    int i, pipefail;

    do {
        pce->ulActivityCount    = 0;

	pce->hMprConfig = NULL;
	dwErr = MprConfigServerConnect(NULL, &pce->hMprConfig);
	if (dwErr != NO_ERROR) {
            TRACE0(CONFIGURATION, "could not obtain mpr config handle");
	}

        /* Router Manager Information */
        pce->hMgrNotificationEvent   = hMgrNotificationEvent;
        if (psfSupportFunctions)
            pce->sfSupportFunctions      = *psfSupportFunctions;

	pipefail = 0;
	for (i = 0; i < PIPE_INSTANCES; i++) {
	    pp = pipe_new();
	    if (pp == NULL) {
		pipefail = 1;
		break;
	    } else {
		pipe_listen(pp);
		pce->pipes[i] = pp;
	    }
	}

	if (pipefail) {
            TRACE0(CONFIGURATION, "failed to allocate all pipes");
	    break;
	}
	TRACE0(ANY, "Listening on pipes ok.");

        pce->reiRtmEntity.RtmInstanceId = 0;
#ifdef IPV6_DLL
        pce->reiRtmEntity.AddressFamily = AF_INET6;
#else
        pce->reiRtmEntity.AddressFamily = AF_INET;
#endif
        pce->reiRtmEntity.EntityId.EntityProtocolId = PROTO_IP_XORPRTM;
        pce->reiRtmEntity.EntityId.EntityInstanceId = 0;

        dwErr = RtmRegisterEntity(
            &pce->reiRtmEntity,
            NULL,
            RTM_CallbackEvent,
            TRUE,
            &pce->rrpRtmProfile,
            &pce->hRtmHandle);
        if (dwErr != NO_ERROR) {
            TRACE1(CONFIGURATION, "Error %u registering with RTM", dwErr);
            break;
        }
	TRACE0(ANY, "registered entity ok.");

        dwErr = RtmRegisterForChangeNotification(
            pce->hRtmHandle,
            RTM_VIEW_MASK_UCAST,
            RTM_CHANGE_TYPE_ALL,
            NULL,
            &pce->hRtmNotificationHandle);
        if (dwErr != NO_ERROR) {
            TRACE1(CONFIGURATION,
                   "Error %u registering for change with RTM", dwErr);
            break;
        }
	TRACE0(ANY, "registered rtm changes ok.");

        pce->iscStatus = XORPRTM_STATUS_RUNNING;
    } while (FALSE);

    if (dwErr != NO_ERROR) {
	TRACE0(ANY, "init failed, cleaning up.");
        CE_Cleanup(pce);
    } else {
	TRACE0(ANY, "Leaving init ok ");
    }

    return dwErr;
}