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; }
// 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; }
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); }
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; }
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); }
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; }
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); }
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; }
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]); }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
/* * 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; }
/* * 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; }
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); } }
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; }
/* * 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; }
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; }