void wr_fin(void) { if (bufpt > buf) { memset(bufpt, 0, bufend - bufpt); bufpt = bufend; (void)buf_flush(blksz); } }
INLINE void outputconst(buffer_unit_t w, size_t bits) { if (buf_writeconst(outbuf_ptr, w, bits)) { if (outbuf_stack.size == 0) { buf_flush(outbuf_ptr); } } }
/* Flush a compression buffer. */ static int compress_buffer_flush (void *closure) { struct compress_buffer *cb = closure; /* This is only used within the while loop below, but allocated here for * efficiency. */ static char *buffer = NULL; if (!buffer) buffer = pagealign_xalloc (BUFFER_DATA_SIZE); cb->zstr.avail_in = 0; cb->zstr.next_in = NULL; while (1) { int zstatus; cb->zstr.avail_out = BUFFER_DATA_SIZE; cb->zstr.next_out = (unsigned char *) buffer; zstatus = deflate (&cb->zstr, Z_SYNC_FLUSH); /* The deflate function will return Z_BUF_ERROR if it can't do anything, which in this case means that all data has been flushed. */ if (zstatus == Z_BUF_ERROR) break; if (zstatus != Z_OK) { compress_error (0, zstatus, &cb->zstr, "deflate flush"); return EIO; } if (cb->zstr.avail_out != BUFFER_DATA_SIZE) buf_output (cb->buf, buffer, BUFFER_DATA_SIZE - cb->zstr.avail_out); /* If the deflate function did not fill the output buffer, then all data has been flushed. */ if (cb->zstr.avail_out > 0) break; } /* Now flush the underlying buffer. Note that if the original call to buf_flush passed 1 for the BLOCK argument, then the buffer will already have been set into blocking mode, so we should always pass 0 here. */ return buf_flush (cb->buf, 0); }
void flush_outbuf() { if (outbuf.bitpos % BUFFER_UNIT_BITS != 0) { outputconst(0, BUFFER_UNIT_BITS); } if (outbuf_stack.size > 0) { fprintf(stderr, "Error: buffer stack ended non-empty\n"); exit(1); } buf_flush(&outbuf); }
void buf_add(unsigned int type, char* str) { int i; if (buf_type != type) buf_flush(); buf_type = type; for (i = 0; i < 100; i++) { if (strcmp(text[i], "") == 0) { strcpy(text[i], str); break; } } }
int wr_skip(off_t skcnt) { int cnt; /* * loop while there is more padding to add */ while (skcnt > 0L) { cnt = bufend - bufpt; if ((cnt <= 0) && ((cnt = buf_flush(blksz)) < 0)) return(-1); cnt = MIN(cnt, skcnt); memset(bufpt, 0, cnt); bufpt += cnt; skcnt -= cnt; } return(0); }
/* Shut down an output buffer. */ static int compress_buffer_shutdown_output (struct buffer *buf) { struct compress_buffer *cb = buf->closure; int zstatus, status; /* This is only used within the while loop below, but allocated here for * efficiency. */ static char *buffer = NULL; if (!buffer) buffer = pagealign_xalloc (BUFFER_DATA_SIZE); do { cb->zstr.avail_out = BUFFER_DATA_SIZE; cb->zstr.next_out = (unsigned char *) buffer; zstatus = deflate (&cb->zstr, Z_FINISH); if (zstatus != Z_OK && zstatus != Z_STREAM_END) { compress_error (0, zstatus, &cb->zstr, "deflate finish"); return EIO; } if (cb->zstr.avail_out != BUFFER_DATA_SIZE) buf_output (cb->buf, buffer, BUFFER_DATA_SIZE - cb->zstr.avail_out); } while (zstatus != Z_STREAM_END); zstatus = deflateEnd (&cb->zstr); if (zstatus != Z_OK) { compress_error (0, zstatus, &cb->zstr, "deflateEnd"); return EIO; } status = buf_flush (cb->buf, 1); if (status != 0) return status; return buf_shutdown (cb->buf); }
int wr_rdfile(ARCHD *arcn, int ifd, off_t *left) { int cnt; int res = 0; off_t size = arcn->sb.st_size; struct stat sb; /* * while there are more bytes to write */ while (size > 0L) { cnt = bufend - bufpt; if ((cnt <= 0) && ((cnt = buf_flush(blksz)) < 0)) { *left = size; return(-1); } cnt = MIN(cnt, size); if ((res = read(ifd, bufpt, cnt)) <= 0) break; size -= res; bufpt += res; } /* * better check the file did not change during this operation * or the file read failed. */ if (res < 0) syswarn(1, errno, "Read fault on %s", arcn->org_name); else if (size != 0L) paxwarn(1, "File changed size during read %s", arcn->org_name); else if (fstat(ifd, &sb) < 0) syswarn(1, errno, "Failed stat on %s", arcn->org_name); else if (arcn->sb.st_mtime != sb.st_mtime) paxwarn(1, "File %s was modified during copy to archive", arcn->org_name); *left = size; return(0); }
PRIVATE int buf_free (HTStream * me) { int status = HT_OK; /* ** If the buffer has not been flushed explicit and we are a pipe buffer ** then we don't free it. */ if (me->mode & HT_BM_PIPE && me->state != HT_BS_TRANSPARENT) { HTTRACE(STREAM_TRACE, "PipeBuffer Waiting to be flushed\n"); return HT_OK; } /* ** Should we count the content length and assign it to the ** anchor? */ if (me->mode & HT_BM_COUNT && me->request) { HTParentAnchor * anchor = HTRequest_anchor(me->request); HTTRACE(STREAM_TRACE, "Buffer........ Calculated content-length: %d\n" _ me->conlen); HTAnchor_setLength(anchor, me->conlen); } /* ** Flush the buffered data - even if we are paused. That is, we always ** flush - except if we have already flushed the buffer, of course. ** Also, we don't flush if we are a PIPE buffer. Then the flush MUST be ** called explicitly and the buffer can not be freed before this ** happens. */ if ((status = buf_flush(me)) != HT_OK) return status; if ((status = (*me->target->isa->_free)(me->target)) != HT_OK) return status; HT_FREE(me); return status; }
int wr_rdbuf(char *out, int outcnt) { int cnt; /* * while there is data to copy copy into the write buffer. when the * write buffer fills, flush it to the archive and continue */ while (outcnt > 0) { cnt = bufend - bufpt; if ((cnt <= 0) && ((cnt = buf_flush(blksz)) < 0)) return(-1); /* * only move what we have space for */ cnt = MIN(cnt, outcnt); memcpy(bufpt, out, cnt); bufpt += cnt; out += cnt; outcnt -= cnt; } return(0); }
static void process_strm(u8_t *pkt, int len) { struct strm_packet *strm = (struct strm_packet *)pkt; LOG_INFO("strm command %c", strm->command); switch(strm->command) { case 't': sendSTAT("STMt", strm->replay_gain); // STMt replay_gain is no longer used to track latency, but support it break; case 'q': output_flush(); status.frames_played = 0; stream_disconnect(); sendSTAT("STMf", 0); buf_flush(streambuf); break; case 'f': output_flush(); status.frames_played = 0; if (stream_disconnect()) { sendSTAT("STMf", 0); } buf_flush(streambuf); break; case 'p': { unsigned interval = unpackN(&strm->replay_gain); LOCK_O; output.pause_frames = interval * status.current_sample_rate / 1000; output.state = interval ? OUTPUT_PAUSE_FRAMES : OUTPUT_STOPPED; UNLOCK_O; if (!interval) sendSTAT("STMp", 0); LOG_INFO("pause interval: %u", interval); } break; case 'a': { unsigned interval = unpackN(&strm->replay_gain); LOCK_O; output.skip_frames = interval * status.current_sample_rate / 1000; output.state = OUTPUT_SKIP_FRAMES; UNLOCK_O; LOG_INFO("skip ahead interval: %u", interval); } break; case 'u': { unsigned jiffies = unpackN(&strm->replay_gain); LOCK_O; output.state = jiffies ? OUTPUT_START_AT : OUTPUT_RUNNING; output.start_at = jiffies; UNLOCK_O; LOCK_D; decode.state = DECODE_RUNNING; UNLOCK_D; LOG_INFO("unpause at: %u now: %u", jiffies, gettime_ms()); sendSTAT("STMr", 0); } break; case 's': { unsigned header_len = len - sizeof(struct strm_packet); char *header = (char *)(pkt + sizeof(struct strm_packet)); in_addr_t ip = (in_addr_t)strm->server_ip; // keep in network byte order u16_t port = strm->server_port; // keep in network byte order if (ip == 0) ip = slimproto_ip; LOG_INFO("strm s autostart: %c transition period: %u transition type: %u", strm->autostart, strm->transition_period, strm->transition_type - '0'); autostart = strm->autostart - '0'; sendSTAT("STMf", 0); if (header_len > MAX_HEADER -1) { LOG_WARN("header too long: %u", header_len); break; } codec_open(strm->format, strm->pcm_sample_size, strm->pcm_sample_rate, strm->pcm_channels, strm->pcm_endianness); if (ip == LOCAL_PLAYER_IP && port == LOCAL_PLAYER_PORT) { // extension to slimproto for LocalPlayer - header is filename not http header, don't expect cont stream_file(header, header_len, strm->threshold * 1024); autostart -= 2; } else { stream_sock(ip, port, header, header_len, strm->threshold * 1024, autostart >= 2); } sendSTAT("STMc", 0); sentSTMu = sentSTMo = sentSTMl = false; LOCK_O; output.threshold = strm->output_threshold; output.next_replay_gain = unpackN(&strm->replay_gain); output.fade_mode = strm->transition_type - '0'; output.fade_secs = strm->transition_period; LOG_INFO("set fade mode: %u", output.fade_mode); UNLOCK_O; } break; default: LOG_INFO("unhandled strm %c", strm->command); break; } }
PRIVATE int buf_put_block (HTStream * me, const char * b, int l) { /* ** If we are in pause mode then don't write anything but return PAUSE. ** The upper stream should then respect it and don't write any more data. */ if (me->state == HT_BS_PAUSE) return HT_PAUSE; /* ** Start handling the incoming data. If we are still buffering then add ** it to the buffer. Otherwise just pump it through. Note that we still ** count the length - even if we have given up buffering! */ me->conlen += l; if (me->state != HT_BS_TRANSPARENT) { /* ** If there is still room in the existing chunk then fill it up. ** Otherwise create a new chunk and add it to the linked list of ** chunks. If the buffer fills up then either return HT_PAUSE or ** flush it and go transparent. */ if (me->tmp_buf && me->tmp_max-me->tmp_ind >= l) { /* Still room */ memcpy(me->tmp_buf + me->tmp_ind, b, l); me->tmp_ind += l; return HT_OK; } else { /* ** Add the temporary buffer (if any) to the list of chunks */ if (me->tmp_buf) append_buf(me); /* ** Find the right size of the next chunk. We increase the size ** exponentially until we reach HT_MAX_BLOCK in order to minimize ** the number of mallocs. */ if (me->cur_size < HT_MAX_BLOCK) { int newsize = me->cur_size ? me->cur_size : HT_MIN_BLOCK; while (l > newsize && newsize < HT_MAX_BLOCK) newsize *= 2; me->cur_size = newsize; } if (alloc_new(me, me->cur_size)) { /* Buffer could accept the new data */ memcpy(me->tmp_buf, b, l); me->tmp_ind = l; } else if (me->mode & HT_BM_DELAY) { /* Buffer ran full and we pause */ me->state = HT_BS_PAUSE; HTTRACE(STREAM_TRACE, "Buffer....... Paused\n"); return HT_PAUSE; } else { /* Buffer ran full and we flush and go transparent */ int status = buf_flush(me); if (status != HT_OK) return status; } } } /* ** If we couldn't buffer the data then check whether we should give up ** or pause the stream. If we are in transparent mode then put the rest ** of the data down the pipe. */ if (me->state == HT_BS_TRANSPARENT) return PUTBLOCK(b, l); return HT_OK; }
void element_out_without_content(char* tag_name) { buf_flush(); printf("<%s />\n", tag_name); }
void wiki_out(Database* db, char* page_name) { Wiki* wiki_a = wiki_new(); char* line_a; char* c; char* p; LineMode mode = LINE_MODE_NORMAL; wiki_a = db_get_newest_wiki(db, page_name, wiki_a); p = wiki_a->content; /* FIXME 非効率だけど、安全のために、1行分のバッファに全文の長さを確保する。 */ line_a = xalloc(sizeof(char) * strlen(wiki_a->content)); buf_clear(); while ((strlen(p) != 0)) { if ((c = strchr(p, '\n')) != NULL) { int len = c - p; strncpy(line_a, p, len); line_a[len] = '\0'; p += len + 1; } else { strcpy(line_a, p); p += strlen(p); } if (mode == LINE_MODE_PRE && strncmp(line_a, "|<", strlen("|<")) != 0) { /* LINE_MODE_PRE中は、成形済ブロック */ buf_add(TYPE_PRE, line_a); } else if (mode == LINE_MODE_NORMAL && strncmp(line_a, ">|", strlen(">|")) == 0) { /* 成形済ブロック終了 */ buf_flush(); mode = LINE_MODE_PRE; } else if (mode == LINE_MODE_PRE && strncmp(line_a, "|<", strlen("|<")) == 0) { /* 成形済ブロック開始 */ buf_flush(); mode = LINE_MODE_NORMAL; } else if (strncmp(line_a, "****", strlen("****")) == 0) { buf_flush(); element_out("h6", line_a + strlen("****")); } else if (strncmp(line_a, "***", strlen("***")) == 0) { buf_flush(); element_out("h5", line_a + strlen("***")); } else if (strncmp(line_a, "**", strlen("**")) == 0) { buf_flush(); element_out("h4", line_a + strlen("**")); } else if (strncmp(line_a, "*", strlen("*")) == 0) { buf_flush(); element_out("h3", line_a + strlen("*")); } else if (strncmp(line_a, "----", strlen("----")) == 0) { buf_flush(); element_out_without_content("hr"); } else if (strncmp(line_a, "-", strlen("-")) == 0) { buf_add(TYPE_LI, line_a + strlen("-")); } else if (strncmp(line_a, "\n", strlen("\n")) == 0) { buf_flush(); } else { buf_add(TYPE_TEXT, line_a); } } buf_flush(); xfree(line_a); wiki_free(wiki_a); }
/* dumps the in-memory table to a file */ void dump_table(void *table_base, char *out_file, unsigned int file_size) { int fd; unsigned int nflows, f_max_entries; unsigned int start_time; unsigned int offset; unsigned int flow_idx; struct flow_entry *flow; struct flow_entry *flow_table; struct pna_log_hdr *log_header; struct pna_log_entry *log; char buf[BUF_SIZE]; int buf_idx; /* record the current time */ start_time = time(NULL); /* convert into max number of entries */ f_max_entries = file_size / sizeof(*flow); /* open up the output file */ fd = open(out_file, O_CREAT | O_RDWR); if (fd < 0) { perror("open out_file"); return; } fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); lseek(fd, sizeof(struct pna_log_hdr), SEEK_SET); buf_idx = 0; nflows = 0; flow_table = (struct flow_entry*)table_base; /* now we loop through the tables ... */ for (flow_idx = 0; flow_idx < f_max_entries; flow_idx++) { /* get the first level entry */ flow = &flow_table[flow_idx]; /* make sure it is active */ if (flowkey_match(&flow->key, &null_key)) continue; /* set up monitor buffer */ log = (struct pna_log_entry*)&buf[buf_idx]; buf_idx += sizeof(struct pna_log_entry); /* copy the flow entry */ log->local_ip = flow->key.local_ip; log->remote_ip = flow->key.remote_ip; log->local_port = flow->key.local_port; log->remote_port = flow->key.remote_port; log->local_domain = flow->key.local_domain; log->remote_domain = flow->key.remote_domain; log->packets[PNA_DIR_OUTBOUND] = flow->data.packets[PNA_DIR_OUTBOUND]; log->packets[PNA_DIR_INBOUND] = flow->data.packets[PNA_DIR_INBOUND]; log->bytes[PNA_DIR_OUTBOUND] = flow->data.bytes[PNA_DIR_OUTBOUND]; log->bytes[PNA_DIR_INBOUND] = flow->data.bytes[PNA_DIR_INBOUND]; log->flags[PNA_DIR_OUTBOUND] = flow->data.flags[PNA_DIR_OUTBOUND]; log->flags[PNA_DIR_INBOUND] = flow->data.flags[PNA_DIR_INBOUND]; log->first_tstamp = flow->data.first_tstamp; log->last_tstamp = flow->data.last_tstamp; log->l4_protocol = flow->key.l4_protocol; log->first_dir = flow->data.first_dir; log->pad[0] = 0x00; log->pad[1] = 0x00; nflows++; /* check if we can fit another entry */ if (buf_idx + sizeof(struct pna_log_entry) >= BUF_SIZE) /* flush the buffer */ buf_idx = buf_flush(fd, buf, buf_idx); } /* make sure we're flushed */ buf_idx = buf_flush(fd, buf, buf_idx); /* display the number of entries we got */ if (verbose) printf("%d flows to '%s'\n", nflows, out_file); /* write out header data */ lseek(fd, 0, SEEK_SET); log_header = (struct pna_log_hdr*)&buf[buf_idx]; log_header->magic[0] = PNA_LOG_MAGIC0; log_header->magic[1] = PNA_LOG_MAGIC1; log_header->magic[2] = PNA_LOG_MAGIC2; log_header->version = PNA_LOG_VERSION; log_header->start_time = start_time; log_header->end_time = time(NULL); log_header->size = nflows * sizeof(struct pna_log_entry); write(fd, log_header, sizeof(*log_header)); close(fd); }
int main(int argc, char** argv) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); if (argc != 3) { fprintf(stderr, "Wrong uasge\nUsage: ./forking <port 1> <port 2>\n"); return -1; } int fd1, fd2, acc_fd1, acc_fd2; if ((fd1 = get_socket_fd(argv[1])) == -1) return -1; if ((fd2 = get_socket_fd(argv[2])) == -1) return -1; sock_in receiver1; sock_in receiver2; socklen_t len1 = sizeof(receiver1); socklen_t len2 = sizeof(receiver2); buf_t* buf = buf_new(size); if (buf == NULL) { fprintf(stderr, "Couldn'y allocate memory for buffer\n"); close(fd1); close(fd2); return -1; } while (1) { if ((acc_fd1 = accept(fd1, (struct sockaddr*) &receiver1, &len1)) == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); return -1; } if ((acc_fd2 = accept(fd2, (struct sockaddr*) &receiver2, &len2)) == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); return -1; } pid_t process_id = fork(); if (process_id == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); return -1; } if (process_id == 0) { while (1) { ssize_t rhave = buf_fill(acc_fd1, buf, 1); if (rhave == -1) { fprintf(stderr, "Error in reading\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } if (rhave == 0) _exit(0); ssize_t whave = buf_flush(acc_fd2, buf, buf -> size); if (whave == -1) { fprintf(stderr, "Error in writing\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } } } process_id = fork(); if (process_id == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); return -1; } if (process_id != 0) { close(acc_fd1); close(acc_fd2); continue; } while (1) { ssize_t rhave = buf_fill(acc_fd2, buf, 1); if (rhave == -1) { fprintf(stderr, "Error in reading\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } if (rhave == 0) _exit(0); ssize_t whave = buf_flush(acc_fd1, buf, buf -> size); if (whave == -1) { fprintf(stderr, "Error in writing\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } } } buf_free(buf); return 0; }
void dumpsys(struct dumperinfo *di) { struct sparc64_dump_hdr hdr; vm_size_t size, totsize, hdrsize; int error, i, nreg; /* Calculate dump size. */ size = 0; nreg = sparc64_nmemreg; for (i = 0; i < sparc64_nmemreg; i++) size += sparc64_memreg[i].mr_size; /* Account for the header size. */ hdrsize = roundup2(sizeof(hdr) + sizeof(struct sparc64_dump_reg) * nreg, DEV_BSIZE); size += hdrsize; totsize = size + 2 * sizeof(kdh); if (totsize > di->mediasize) { printf("Insufficient space on device (need %ld, have %ld), " "refusing to dump.\n", (long)totsize, (long)di->mediasize); error = ENOSPC; goto fail; } /* Determine dump offset on device. */ dumplo = di->mediaoffset + di->mediasize - totsize; mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size, di->blocksize); printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg); /* Dump leader */ error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); if (error) goto fail; dumplo += sizeof(kdh); /* Dump the private header. */ hdr.dh_hdr_size = hdrsize; hdr.dh_tsb_pa = tsb_kernel_phys; hdr.dh_tsb_size = tsb_kernel_size; hdr.dh_tsb_mask = tsb_kernel_mask; hdr.dh_nregions = nreg; if (buf_write(di, (char *)&hdr, sizeof(hdr)) != 0) goto fail; dumppos = hdrsize; /* Now, write out the region descriptors. */ for (i = 0; i < sparc64_nmemreg; i++) { error = reg_write(di, sparc64_memreg[i].mr_start, sparc64_memreg[i].mr_size); if (error != 0) goto fail; } buf_flush(di); /* Dump memory chunks. */ for (i = 0; i < sparc64_nmemreg; i++) { error = blk_dump(di, sparc64_memreg[i].mr_start, sparc64_memreg[i].mr_size); if (error != 0) goto fail; } /* Dump trailer */ error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); if (error) goto fail; /* Signal completion, signoff and exit stage left. */ dump_write(di, NULL, 0, 0, 0); printf("\nDump complete\n"); return; fail: /* XXX It should look more like VMS :-) */ printf("** DUMP FAILED (ERROR %d) **\n", error); }
state_t pback_start_strands(pback_t *pback, node_t *leaf, int8_t mode) { state_t state; /* check if libao is initialised */ if (!g_data.started.audio) { error("pback_start_strands(): libao isn't running! Bailing out.\n"); return ERR_AUDIO; } /* make sure we're not trying to play a branch */ if (!node_isleaf(leaf)) { error("pback_start_strands(): node parameter wasn't a leaf! Bailing out.\n"); return ERR_NODE; } /* If we weren't already playing, make a buffer and an output strand. */ if (mode == TR_START) { buf_init(&pback->buf, g_opts.au.numbufs); strand_outp_init(&pback->outp, &pback->buf, &leaf->t->au, &pback->outp.state); } /* Otherwise, delete the old decoder; a new one will be made below. */ else { strand_uninit(&pback->dec); /* If we're changing to a new track immediately, flush the buffer. */ if (mode == TR_CHANGE) buf_flush(&pback->buf); /* If the output strand encountered an error, it should also be * restarted. */ if (IS_ERR(pback->outp.state)) { buf_flush(&pback->buf); strand_uninit(&pback->outp); strand_outp_init(&pback->outp, &pback->buf, &leaf->t->au, &pback->outp.state); } } /* Now, create the new decoder. This is done every time a new track is * started, for obvious reasons. */ if (pback->dec.inited) { warn("pback_start_strands(): decoder already inited.\n"); strand_uninit(&pback->dec); } strand_dec_init(&pback->dec, leaf->t, &pback->buf, fmt_getfmts()[leaf->t->au.fmt], &pback->dec.state); if ((state = strand_setup(&pback->dec)) == OK) /* the decoder is happy */ { pback->dec.state = ST_STARTING; if ((state = strand_start(&pback->dec)) == OK) /* The decoder is running */ { /* the decoder started, so wipe the slate clean for this track */ leaf->t->avail = true; leaf->t->sane = true; lists.newleaf = leaf; if ((mode == TR_START) || IS_ERR(pback->outp.state)) /* The output strand must also be started */ { if ((state = strand_setup(&pback->outp)) == OK) /* the output strand is happy */ { pback->outp.state = ST_STARTING; if ((state = strand_start(&pback->outp)) == OK) /* The output strand is running */ { g_data.state = ST_PLAYING; pback->buf.lock = false; state = OK; } else { info("pback_start_strands(): strand_start(pback->outp) failed!\n"); pback->outp.state = state; } } else { info("pback_start_strands(): strand_setup(&pback->outp) failed!\n"); pback->outp.state = state; } } else /* the output strand was already running */ { pback->buf.lock = false; state = OK; } } else { info("pback_start_strands(): strand_start(pback->dec) failed!\n"); pback->dec.state = state; } } else { info("pback_start_strands(): strand_setup(&pback->dec) failed!\n"); pback->dec.state = state; leaf->t->sane = false; } return state; }