[BACK]Return to abuf.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Annotation of src/usr.bin/aucat/abuf.c, Revision 1.18

1.18    ! ratchov     1: /*     $OpenBSD: abuf.c,v 1.17 2010/01/10 21:47:41 ratchov Exp $       */
1.1       ratchov     2: /*
                      3:  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: /*
                     18:  * Simple byte fifo. It has one reader and one writer. The abuf
                     19:  * structure is used to interconnect audio processing units (aproc
                     20:  * structures).
                     21:  *
                     22:  * The abuf data is split in two parts: (1) valid data available to the reader
                     23:  * (2) space available to the writer, which is not necessarily unused. It works
                     24:  * as follows: the write starts filling at offset (start + used), once the data
                     25:  * is ready, the writer adds to used the count of bytes available.
1.7       ratchov    26:  */
                     27: /*
                     28:  * TODO
1.1       ratchov    29:  *
1.7       ratchov    30:  *     use blocks instead of frames for WOK and ROK macros. If necessary
                     31:  *     (unlikely) define reader block size and writer blocks size to
                     32:  *     ease pipe/socket implementation
1.1       ratchov    33:  */
                     34: #include <err.h>
1.11      ratchov    35: #include <stdarg.h>
1.1       ratchov    36: #include <stdio.h>
                     37: #include <stdlib.h>
1.4       ratchov    38: #include <string.h>
1.1       ratchov    39:
1.13      ratchov    40: #include "abuf.h"
1.8       ratchov    41: #include "aparams.h"
1.1       ratchov    42: #include "aproc.h"
1.13      ratchov    43: #include "conf.h"
1.17      ratchov    44: #ifdef DEBUG
                     45: #include "dbg.h"
                     46: #endif
1.1       ratchov    47:
1.17      ratchov    48: #ifdef DEBUG
                     49: void
                     50: abuf_dbg(struct abuf *buf)
                     51: {
                     52:        if (buf->wproc) {
                     53:                aproc_dbg(buf->wproc);
                     54:        } else {
                     55:                dbg_puts("none");
                     56:        }
                     57:        dbg_puts(buf->inuse ? "=>" : "->");
                     58:        if (buf->rproc) {
                     59:                aproc_dbg(buf->rproc);
                     60:        } else {
                     61:                dbg_puts("none");
                     62:        }
                     63: }
                     64:
                     65: void
                     66: abuf_dump(struct abuf *buf)
                     67: {
                     68:        abuf_dbg(buf);
                     69:        dbg_puts(": used = ");
                     70:        dbg_putu(buf->used);
                     71:        dbg_puts("/");
                     72:        dbg_putu(buf->len);
                     73:        dbg_puts(" start = ");
                     74:        dbg_putu(buf->start);
                     75:        dbg_puts("\n");
                     76: }
                     77: #endif
1.7       ratchov    78:
1.1       ratchov    79: struct abuf *
1.8       ratchov    80: abuf_new(unsigned nfr, struct aparams *par)
1.1       ratchov    81: {
                     82:        struct abuf *buf;
1.8       ratchov    83:        unsigned len, bpf;
1.1       ratchov    84:
1.8       ratchov    85:        bpf = aparams_bpf(par);
1.1       ratchov    86:        len = nfr * bpf;
                     87:        buf = malloc(sizeof(struct abuf) + len);
                     88:        if (buf == NULL) {
1.17      ratchov    89: #ifdef DEBUG
                     90:                dbg_puts("couldn't allocate abuf of ");
                     91:                dbg_putu(nfr);
                     92:                dbg_puts("fr * ");
                     93:                dbg_putu(bpf);
                     94:                dbg_puts("bpf\n");
                     95:                dbg_panic();
                     96: #else
1.15      ratchov    97:                err(1, "malloc");
1.17      ratchov    98: #endif
1.1       ratchov    99:        }
                    100:        buf->bpf = bpf;
1.8       ratchov   101:        buf->cmin = par->cmin;
                    102:        buf->cmax = par->cmax;
1.7       ratchov   103:        buf->inuse = 0;
1.1       ratchov   104:
                    105:        /*
                    106:         * fill fifo pointers
                    107:         */
                    108:        buf->len = len;
                    109:        buf->used = 0;
                    110:        buf->start = 0;
1.5       ratchov   111:        buf->abspos = 0;
1.4       ratchov   112:        buf->silence = 0;
                    113:        buf->drop = 0;
1.1       ratchov   114:        buf->rproc = NULL;
                    115:        buf->wproc = NULL;
1.7       ratchov   116:        buf->duplex = NULL;
1.1       ratchov   117:        return buf;
                    118: }
                    119:
                    120: void
                    121: abuf_del(struct abuf *buf)
                    122: {
1.7       ratchov   123:        if (buf->duplex)
                    124:                buf->duplex->duplex = NULL;
1.17      ratchov   125: #ifdef DEBUG
                    126:        if (buf->rproc || buf->wproc) {
                    127:                abuf_dbg(buf);
                    128:                dbg_puts(": can't delete referenced buffer\n");
                    129:                dbg_panic();
                    130:        }
                    131:        if (ABUF_ROK(buf)) {
                    132:                /*
                    133:                 * XXX : we should call abort(), here.
                    134:                 * However, poll() doesn't seem to return POLLHUP,
                    135:                 * so the reader is never destroyed; instead it appears
                    136:                 * as blocked. Fix file_poll(), if fixable, and add
                    137:                 * a call to abord() here.
                    138:                 */
                    139:                if (debug_level >= 3) {
                    140:                        abuf_dbg(buf);
                    141:                        dbg_puts(": deleting non-empty buffer, used = ");
                    142:                        dbg_putu(buf->used);
                    143:                        dbg_puts("\n");
                    144:                }
                    145:        }
                    146: #endif
1.1       ratchov   147:        free(buf);
1.9       ratchov   148: }
                    149:
                    150: /*
1.13      ratchov   151:  * Clear buffer contents.
1.9       ratchov   152:  */
                    153: void
                    154: abuf_clear(struct abuf *buf)
                    155: {
1.17      ratchov   156: #ifdef DEBUG
                    157:        if (debug_level >= 3) {
                    158:                abuf_dbg(buf);
                    159:                dbg_puts(": cleared\n");
                    160:        }
                    161: #endif
1.9       ratchov   162:        buf->used = 0;
                    163:        buf->start = 0;
                    164:        buf->abspos = 0;
                    165:        buf->silence = 0;
                    166:        buf->drop = 0;
1.1       ratchov   167: }
                    168:
                    169: /*
                    170:  * Get a pointer to the readable block at the given offset.
                    171:  */
                    172: unsigned char *
                    173: abuf_rgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
                    174: {
                    175:        unsigned count, start, used;
                    176:
                    177:        start = buf->start + ofs;
                    178:        used = buf->used - ofs;
1.6       ratchov   179:        if (start >= buf->len)
                    180:                start -= buf->len;
1.17      ratchov   181: #ifdef DEBUG
                    182:        if (start >= buf->len || used > buf->used) {
                    183:                abuf_dump(buf);
                    184:                dbg_puts(": rgetblk: bad ofs = ");
                    185:                dbg_putu(ofs);
                    186:                dbg_puts("\n");
                    187:                dbg_panic();
                    188:        }
                    189: #endif
1.1       ratchov   190:        count = buf->len - start;
                    191:        if (count > used)
                    192:                count = used;
                    193:        *rsize = count;
1.16      ratchov   194:        return (unsigned char *)buf + sizeof(struct abuf) + start;
1.3       ratchov   195: }
                    196:
                    197: /*
1.13      ratchov   198:  * Discard the block at the start postion.
1.3       ratchov   199:  */
                    200: void
                    201: abuf_rdiscard(struct abuf *buf, unsigned count)
                    202: {
1.17      ratchov   203: #ifdef DEBUG
                    204:        if (count > buf->used) {
                    205:                abuf_dump(buf);
                    206:                dbg_puts(": rdiscard: bad count = ");
                    207:                dbg_putu(count);
                    208:                dbg_puts("\n");
                    209:                dbg_panic();
                    210:        }
                    211: #endif
1.3       ratchov   212:        buf->used -= count;
                    213:        buf->start += count;
                    214:        if (buf->start >= buf->len)
                    215:                buf->start -= buf->len;
1.5       ratchov   216:        buf->abspos += count;
1.3       ratchov   217: }
                    218:
                    219: /*
1.13      ratchov   220:  * Commit the data written at the end postion.
1.3       ratchov   221:  */
                    222: void
                    223: abuf_wcommit(struct abuf *buf, unsigned count)
                    224: {
1.17      ratchov   225: #ifdef DEBUG
                    226:        if (count > (buf->len - buf->used)) {
                    227:                abuf_dump(buf);
                    228:                dbg_puts(": rdiscard: bad count = ");
                    229:                dbg_putu(count);
                    230:                dbg_puts("\n");
                    231:                dbg_panic();
                    232:        }
                    233: #endif
1.3       ratchov   234:        buf->used += count;
1.1       ratchov   235: }
                    236:
                    237: /*
                    238:  * Get a pointer to the writable block at offset ofs.
                    239:  */
                    240: unsigned char *
                    241: abuf_wgetblk(struct abuf *buf, unsigned *rsize, unsigned ofs)
                    242: {
                    243:        unsigned end, avail, count;
                    244:
                    245:
                    246:        end = buf->start + buf->used + ofs;
                    247:        if (end >= buf->len)
                    248:                end -= buf->len;
1.17      ratchov   249: #ifdef DEBUG
                    250:        if (end >= buf->len) {
                    251:                abuf_dump(buf);
1.18    ! ratchov   252:                dbg_puts(": wgetblk: bad ofs = ");
1.17      ratchov   253:                dbg_putu(ofs);
                    254:                dbg_puts("\n");
                    255:                dbg_panic();
                    256:        }
                    257: #endif
1.1       ratchov   258:        avail = buf->len - (buf->used + ofs);
                    259:        count = buf->len - end;
                    260:        if (count > avail)
                    261:                        count = avail;
                    262:        *rsize = count;
1.16      ratchov   263:        return (unsigned char *)buf + sizeof(struct abuf) + end;
1.1       ratchov   264: }
                    265:
                    266: /*
1.13      ratchov   267:  * Flush buffer either by dropping samples or by calling the aproc
                    268:  * call-back to consume data. Return 0 if blocked, 1 otherwise.
1.4       ratchov   269:  */
                    270: int
                    271: abuf_flush_do(struct abuf *buf)
                    272: {
                    273:        struct aproc *p;
                    274:        unsigned count;
                    275:
                    276:        if (buf->drop > 0) {
                    277:                count = buf->drop;
                    278:                if (count > buf->used)
                    279:                        count = buf->used;
1.7       ratchov   280:                if (count == 0) {
1.17      ratchov   281: #ifdef DEBUG
                    282:                        if (debug_level >= 4) {
                    283:                                abuf_dbg(buf);
                    284:                                dbg_puts(": flush: no data to drop\n");
                    285:                        }
                    286: #endif
1.7       ratchov   287:                        return 0;
                    288:                }
1.4       ratchov   289:                abuf_rdiscard(buf, count);
                    290:                buf->drop -= count;
1.17      ratchov   291: #ifdef DEBUG
                    292:                if (debug_level >= 4) {
                    293:                        abuf_dbg(buf);
                    294:                        dbg_puts(": flush: dropped ");
                    295:                        dbg_putu(count);
                    296:                        dbg_puts(", to drop = ");
                    297:                        dbg_putu(buf->drop);
                    298:                        dbg_puts("\n");
                    299:                }
                    300: #endif
1.4       ratchov   301:        } else {
                    302:                p = buf->rproc;
1.15      ratchov   303:                if (!p)
                    304:                        return 0;
1.17      ratchov   305: #ifdef DEBUG
                    306:                if (debug_level >= 4) {
                    307:                        aproc_dbg(p);
                    308:                        dbg_puts(": in\n");
                    309:                }
                    310: #endif
1.15      ratchov   311:                if (!p->ops->in(p, buf))
1.4       ratchov   312:                        return 0;
                    313:        }
                    314:        return 1;
                    315: }
                    316:
                    317: /*
1.13      ratchov   318:  * Fill the buffer either by generating silence or by calling the aproc
                    319:  * call-back to provide data. Return 0 if blocked, 1 otherwise.
1.4       ratchov   320:  */
                    321: int
                    322: abuf_fill_do(struct abuf *buf)
                    323: {
                    324:        struct aproc *p;
                    325:        unsigned char *data;
                    326:        unsigned count;
                    327:
                    328:        if (buf->silence > 0) {
                    329:                data = abuf_wgetblk(buf, &count, 0);
                    330:                if (count >= buf->silence)
                    331:                        count = buf->silence;
1.7       ratchov   332:                if (count == 0) {
1.17      ratchov   333: #ifdef DEBUG
                    334:                        if (debug_level >= 4) {
                    335:                                abuf_dbg(buf);
                    336:                                dbg_puts(": fill: no space for silence\n");
                    337:                        }
                    338: #endif
1.7       ratchov   339:                        return 0;
                    340:                }
1.4       ratchov   341:                memset(data, 0, count);
                    342:                abuf_wcommit(buf, count);
                    343:                buf->silence -= count;
1.17      ratchov   344: #ifdef DEBUG
                    345:                if (debug_level >= 4) {
                    346:                        abuf_dbg(buf);
                    347:                        dbg_puts(": fill: inerted ");
                    348:                        dbg_putu(count);
                    349:                        dbg_puts(", remaining silence = ");
                    350:                        dbg_putu(buf->silence);
                    351:                        dbg_puts("\n");
                    352:                }
                    353: #endif
1.7       ratchov   354:                p = buf->wproc;
1.4       ratchov   355:        } else {
                    356:                p = buf->wproc;
1.15      ratchov   357:                if (!p)
                    358:                        return 0;
1.17      ratchov   359: #ifdef DEBUG
                    360:                if (debug_level >= 4) {
                    361:                        aproc_dbg(p);
                    362:                        dbg_puts(": out\n");
                    363:                }
                    364: #endif
1.15      ratchov   365:                if (!p->ops->out(p, buf)) {
1.4       ratchov   366:                        return 0;
1.7       ratchov   367:                }
                    368:        }
                    369:        return 1;
                    370: }
                    371:
                    372: /*
                    373:  * Notify the reader that there will be no more input (producer
1.13      ratchov   374:  * disappeared) and destroy the buffer.
1.7       ratchov   375:  */
                    376: void
                    377: abuf_eof_do(struct abuf *buf)
                    378: {
                    379:        struct aproc *p;
                    380:
                    381:        p = buf->rproc;
                    382:        if (p) {
                    383:                buf->rproc = NULL;
                    384:                LIST_REMOVE(buf, ient);
                    385:                buf->inuse++;
1.17      ratchov   386: #ifdef DEBUG
                    387:                if (debug_level >= 4) {
                    388:                        aproc_dbg(p);
                    389:                        dbg_puts(": eof\n");
                    390:                }
                    391: #endif
1.7       ratchov   392:                p->ops->eof(p, buf);
                    393:                buf->inuse--;
1.15      ratchov   394:        }
1.7       ratchov   395:        abuf_del(buf);
                    396: }
                    397:
                    398: /*
                    399:  * Notify the writer that the buffer has no more consumer,
1.13      ratchov   400:  * and destroy the buffer.
1.7       ratchov   401:  */
                    402: void
                    403: abuf_hup_do(struct abuf *buf)
                    404: {
                    405:        struct aproc *p;
                    406:
                    407:        if (ABUF_ROK(buf)) {
1.17      ratchov   408: #ifdef DEBUG
                    409:                if (debug_level >= 3) {
                    410:                        abuf_dbg(buf);
                    411:                        dbg_puts(": hup: lost ");
                    412:                        dbg_putu(buf->used);
                    413:                        dbg_puts(" bytes\n");
                    414:                }
                    415: #endif
1.7       ratchov   416:                buf->used = 0;
                    417:        }
                    418:        p = buf->wproc;
                    419:        if (p != NULL) {
                    420:                buf->wproc = NULL;
                    421:                LIST_REMOVE(buf, oent);
                    422:                buf->inuse++;
1.17      ratchov   423: #ifdef DEBUG
                    424:                if (debug_level >= 3) {
                    425:                        aproc_dbg(p);
                    426:                        dbg_puts(": hup\n");
                    427:                }
                    428: #endif
1.7       ratchov   429:                p->ops->hup(p, buf);
                    430:                buf->inuse--;
1.15      ratchov   431:        }
1.7       ratchov   432:        abuf_del(buf);
                    433: }
                    434:
                    435: /*
                    436:  * Notify the read end of the buffer that there is input available
                    437:  * and that data can be processed again.
                    438:  */
                    439: int
                    440: abuf_flush(struct abuf *buf)
1.10      ratchov   441: {
1.7       ratchov   442:        if (buf->inuse) {
1.17      ratchov   443: #ifdef DEBUG
                    444:                if (debug_level >= 4) {
                    445:                        abuf_dbg(buf);
                    446:                        dbg_puts(": flush blocked (inuse)\n");
                    447:                }
                    448: #endif
1.7       ratchov   449:        } else {
                    450:                buf->inuse++;
                    451:                for (;;) {
                    452:                        if (!abuf_flush_do(buf))
                    453:                                break;
                    454:                }
                    455:                buf->inuse--;
                    456:                if (ABUF_HUP(buf)) {
                    457:                        abuf_hup_do(buf);
                    458:                        return 0;
                    459:                }
1.4       ratchov   460:        }
                    461:        return 1;
                    462: }
                    463:
                    464: /*
1.1       ratchov   465:  * Notify the write end of the buffer that there is room and data can be
                    466:  * written again. This routine can only be called from the out()
                    467:  * call-back of the reader.
                    468:  *
1.7       ratchov   469:  * Return 1 if the buffer was filled, and 0 if eof condition occured. The
1.13      ratchov   470:  * reader must detach the buffer on EOF condition, since its aproc->eof()
1.7       ratchov   471:  * call-back will never be called.
1.1       ratchov   472:  */
1.7       ratchov   473: int
1.1       ratchov   474: abuf_fill(struct abuf *buf)
                    475: {
1.7       ratchov   476:        if (buf->inuse) {
1.17      ratchov   477: #ifdef DEBUG
                    478:                if (debug_level >= 4) {
                    479:                        abuf_dbg(buf);
                    480:                        dbg_puts(": fill blocked (inuse)\n");
                    481:                }
                    482: #endif
1.7       ratchov   483:        } else {
                    484:                buf->inuse++;
                    485:                for (;;) {
                    486:                        if (!abuf_fill_do(buf))
                    487:                                break;
                    488:                }
                    489:                buf->inuse--;
                    490:                if (ABUF_EOF(buf)) {
                    491:                        abuf_eof_do(buf);
                    492:                        return 0;
                    493:                }
1.1       ratchov   494:        }
1.7       ratchov   495:        return 1;
1.1       ratchov   496: }
                    497:
                    498: /*
                    499:  * Run a read/write loop on the buffer until either the reader or the
1.13      ratchov   500:  * writer blocks, or until the buffer reaches eofs. We can not get hup here,
1.1       ratchov   501:  * since hup() is only called from terminal nodes, from the main loop.
                    502:  *
                    503:  * NOTE: The buffer may disappear (ie. be free()ed) if eof is reached, so
                    504:  * do not keep references to the buffer or to its writer or reader.
                    505:  */
                    506: void
                    507: abuf_run(struct abuf *buf)
                    508: {
                    509:        int canfill = 1, canflush = 1;
                    510:
1.7       ratchov   511:        if (buf->inuse) {
1.17      ratchov   512: #ifdef DEBUG
                    513:                if (debug_level >= 4) {
                    514:                        abuf_dbg(buf);
                    515:                        dbg_puts(": run blocked (inuse)\n");
                    516:                }
                    517: #endif
1.7       ratchov   518:                return;
                    519:        }
                    520:        buf->inuse++;
1.1       ratchov   521:        for (;;) {
1.7       ratchov   522:                if (canfill) {
                    523:                        if (!abuf_fill_do(buf))
                    524:                                canfill = 0;
                    525:                        else
                    526:                                canflush = 1;
                    527:                } else if (canflush) {
                    528:                        if (!abuf_flush_do(buf))
                    529:                                canflush = 0;
                    530:                        else
                    531:                                canfill = 1;
1.1       ratchov   532:                } else
1.7       ratchov   533:                        break;
                    534:        }
                    535:        buf->inuse--;
                    536:        if (ABUF_EOF(buf)) {
                    537:                abuf_eof_do(buf);
                    538:                return;
                    539:        }
                    540:        if (ABUF_HUP(buf)) {
                    541:                abuf_hup_do(buf);
                    542:                return;
1.1       ratchov   543:        }
                    544: }
                    545:
                    546: /*
                    547:  * Notify the reader that there will be no more input (producer
                    548:  * disappeared). The buffer is flushed and eof() is called only if all
                    549:  * data is flushed.
                    550:  */
                    551: void
                    552: abuf_eof(struct abuf *buf)
                    553: {
1.17      ratchov   554: #ifdef DEBUG
                    555:        if (debug_level >= 3) {
                    556:                abuf_dbg(buf);
                    557:                dbg_puts(": eof requested\n");
                    558:        }
                    559:        if (buf->wproc == NULL) {
                    560:                abuf_dbg(buf);
                    561:                dbg_puts(": eof, no writer\n");
                    562:                dbg_panic();
                    563:        }
                    564: #endif
1.7       ratchov   565:        LIST_REMOVE(buf, oent);
1.1       ratchov   566:        buf->wproc = NULL;
                    567:        if (buf->rproc != NULL) {
1.7       ratchov   568:                if (!abuf_flush(buf))
1.10      ratchov   569:                        return;
1.1       ratchov   570:                if (ABUF_ROK(buf)) {
                    571:                        /*
                    572:                         * Could not flush everything, the reader will
                    573:                         * have a chance to delete the abuf later.
                    574:                         */
1.17      ratchov   575: #ifdef DEBUG
                    576:                        if (debug_level >= 3) {
                    577:                                abuf_dbg(buf);
                    578:                                dbg_puts(": eof, blocked (drain)\n");
                    579:                        }
                    580: #endif
1.1       ratchov   581:                        return;
                    582:                }
                    583:        }
1.7       ratchov   584:        if (buf->inuse) {
1.17      ratchov   585: #ifdef DEBUG
                    586:                if (debug_level >= 3) {
                    587:                        abuf_dbg(buf);
                    588:                        dbg_puts(": eof, blocked (inuse)\n");
                    589:                }
                    590: #endif
1.7       ratchov   591:                return;
                    592:        }
                    593:        abuf_eof_do(buf);
1.1       ratchov   594: }
                    595:
                    596: /*
                    597:  * Notify the writer that the buffer has no more consumer,
                    598:  * and that no more data will accepted.
                    599:  */
                    600: void
                    601: abuf_hup(struct abuf *buf)
                    602: {
1.17      ratchov   603: #ifdef DEBUG
                    604:        if (debug_level >= 3) {
                    605:                abuf_dbg(buf);
                    606:                dbg_puts(": hup requested\n");
                    607:        }
                    608:        if (buf->rproc == NULL) {
                    609:                abuf_dbg(buf);
                    610:                dbg_puts(": hup, no reader\n");
                    611:                dbg_panic();
                    612:        }
                    613: #endif
1.1       ratchov   614:        buf->rproc = NULL;
1.7       ratchov   615:        LIST_REMOVE(buf, ient);
1.1       ratchov   616:        if (buf->wproc != NULL) {
1.7       ratchov   617:                if (buf->inuse) {
1.17      ratchov   618: #ifdef DEBUG
                    619:                        if (debug_level >= 3) {
                    620:                                abuf_dbg(buf);
                    621:                                dbg_puts(": eof, blocked (inuse)\n");
                    622:                        }
                    623: #endif
1.7       ratchov   624:                        return;
1.1       ratchov   625:                }
                    626:        }
1.7       ratchov   627:        abuf_hup_do(buf);
                    628: }
                    629:
                    630: /*
                    631:  * Notify the reader of the change of its real-time position
                    632:  */
                    633: void
                    634: abuf_ipos(struct abuf *buf, int delta)
                    635: {
                    636:        struct aproc *p = buf->rproc;
                    637:
                    638:        if (p && p->ops->ipos) {
                    639:                buf->inuse++;
1.17      ratchov   640: #ifdef DEBUG
                    641:                if (debug_level >= 4) {
                    642:                        aproc_dbg(p);
                    643:                        dbg_puts(": ipos delta = ");
                    644:                        dbg_puti(delta);
                    645:                        dbg_puts("\n");
                    646:                }
                    647: #endif
1.10      ratchov   648:                p->ops->ipos(p, buf, delta);
1.7       ratchov   649:                buf->inuse--;
                    650:        }
                    651:        if (ABUF_HUP(buf))
                    652:                abuf_hup_do(buf);
                    653: }
                    654:
                    655: /*
                    656:  * Notify the writer of the change of its real-time position
                    657:  */
                    658: void
                    659: abuf_opos(struct abuf *buf, int delta)
                    660: {
                    661:        struct aproc *p = buf->wproc;
1.10      ratchov   662:
1.7       ratchov   663:        if (p && p->ops->opos) {
                    664:                buf->inuse++;
1.17      ratchov   665: #ifdef DEBUG
                    666:                if (debug_level >= 4) {
                    667:                        aproc_dbg(p);
                    668:                        dbg_puts(": opos delta = ");
                    669:                        dbg_puti(delta);
                    670:                        dbg_puts("\n");
                    671:                }
                    672: #endif
1.7       ratchov   673:                p->ops->opos(p, buf, delta);
                    674:                buf->inuse--;
                    675:        }
                    676:        if (ABUF_HUP(buf))
                    677:                abuf_hup_do(buf);
1.1       ratchov   678: }