📄 fifo.c
字号:
if (faio_pid == 0) { /* child process */ raisepri(1); /* almost max priority */#ifdef USE_OS2SHM DosGetSharedMem(buf,3); /* PAG_READ|PAG_WRITE */#endif /* Ignoring SIGALRM cures the SCO usleep() bug *//* signal(SIGALRM, SIG_IGN);*/ faio_reader(tracks, track); /* NOTREACHED */ } else { faio_didwait = FALSE; /* close all file-descriptors that only the child will use */ for (n = 1; n <= tracks; n++) close(track[n].f); } return (TRUE);}EXPORT BOOLawait_faio(){ int n; int lastfd = -1; faio_t *f; /* * Wait until the reader is active and has filled the buffer. */ if (lverbose || debug) { printf("Waiting for reader process to fill input buffer ... "); flush(); } faio_wait_on_buffer(faio_ref(faio_buffers - 1), owner_reader, 500*MSECS, 0); if (lverbose || debug) printf("input buffer ready.\n"); sp->empty = sp->full = 0L; /* set correct stat state */ sp->cont_low = faio_buffers; /* set cont to max value */ f = faio_ref(0); for (n = 0; n < faio_buffers; n++, f++) { if (f->fd != lastfd && f->fd == STDIN_FILENO && f->len == 0) { errmsgno(EX_BAD, "Premature EOF on stdin.\n"); kill(faio_pid, SIGKILL); return (FALSE); } lastfd = f->fd; } return (TRUE);}EXPORT voidkill_faio(){ if (faio_pid > 0) kill(faio_pid, SIGKILL);}EXPORT intwait_faio(){ if (faio_pid > 0 && !faio_didwait) return (wait(0)); faio_didwait = TRUE; return (0);}LOCAL voidfaio_reader(tracks, track) int tracks; track_t *track;{ /* This function should not return, but _exit. */ int trackno; if (debug) printf("\nfaio_reader starting\n"); for (trackno = 1; trackno <= tracks; trackno++) { if (debug) printf("\nfaio_reader reading track %d\n", trackno); faio_read_track(&track[trackno]); } sp->done++; if (debug) printf("\nfaio_reader all tracks read, exiting\n"); /* Prevent hang if buffer is larger than all the tracks combined */ if (sp->gets == 0) faio_ref(faio_buffers - 1)->owner = owner_reader;#ifdef USE_OS2SHM DosFreeMem(buf); sleep(30000); /* XXX If calling _exit() here the parent process seems to be blocked */ /* XXX This should be fixed soon */#endif if (debug) error("\nfaio_reader _exit(0)\n"); _exit(0);}#ifndef faio_refLOCAL faio_t *faio_ref(n) int n;{ return (&((faio_t *)buf)[n]);}#endifLOCAL voidfaio_read_track(trackp) track_t *trackp;{ int fd = trackp->f; int bytespt = trackp->secsize * trackp->secspt; int l; long tracksize = trackp->tracksize; long bytes_read = 0L; long bytes_to_read; if (bytespt > faio_buf_size) { comerrno(EX_BAD, "faio_read_track fatal: secsize %d secspt %d, bytespt(%d) > %d !!\n", trackp->secsize, trackp->secspt, bytespt, faio_buf_size); } do { bytes_to_read = bytespt; if (tracksize > 0) { bytes_to_read = tracksize - bytes_read; if (bytes_to_read > bytespt) bytes_to_read = bytespt; } l = faio_read_segment(fd, faio_ref(buf_idx), bytes_to_read); if (++buf_idx >= faio_buffers) buf_idx = 0; if (l <= 0) break; bytes_read += l; } while (tracksize < 0 || bytes_read < tracksize); close(fd); /* Don't keep files open longer than neccesary */}LOCAL voidfaio_wait_on_buffer(f, s, delay, max_wait) faio_t *f; fowner_t s; unsigned long delay; unsigned long max_wait;{ unsigned long max_loops; if (f->owner == s) return; /* return immediately if the buffer is ours */ if (s == owner_reader) sp->empty++; else sp->full++; max_loops = max_wait / delay + 1; while (max_wait == 0 || max_loops--) { USDEBUG1; usleep(delay); USDEBUG2; if (f->owner == s) return; } if (debug) { errmsgno(EX_BAD, "%lu microseconds passed waiting for %d current: %d idx: %d\n", max_wait, s, f->owner, (f - faio_ref(0))/sizeof(*f)); } comerrno(EX_BAD, "faio_wait_on_buffer for %s timed out.\n", (s > owner_faio || s < owner_none) ? "bad_owner" : onames[s]);}LOCAL intfaio_read_segment(fd, f, len) int fd; faio_t *f; int len;{ int l; faio_wait_on_buffer(f, owner_writer, WRITER_DELAY, WRITER_MAXWAIT); f->fd = fd; l = read_buf(fd, f->bufp, len); f->len = l; f->saved_errno = errno; f->owner = owner_reader; sp->puts++; return l;}EXPORT intfaio_read_buf(fd, bp, size) int fd; char *bp; int size;{ char *bufp; int len = faio_get_buf(fd, &bufp, size); if (len > 0) { movebytes(bufp, bp, len); } return len;}EXPORT intfaio_get_buf(fd, bpp, size) int fd; char **bpp; int size;{ faio_t *f; int len;again: f = faio_ref(buf_idx); if (f->owner == owner_faio) { f->owner = owner_writer; if (++buf_idx >= faio_buffers) buf_idx = 0; f = faio_ref(buf_idx); } if ((sp->puts - sp->gets) < sp->cont_low && sp->done == 0) { EDEBUG(("gets: %d puts: %d cont: %d low: %d\n", sp->gets, sp->puts, sp->puts - sp->gets, sp->cont_low)); sp->cont_low = sp->puts - sp->gets; } faio_wait_on_buffer(f, owner_reader, READER_DELAY, READER_MAXWAIT); len = f->len; if (f->fd != fd) { if (f->len == 0) { /* * If the tracksize for this track was known, and * the tracksize is 0 mod bytespt, this happens. */ goto again; } comerrno(EX_BAD, "faio_get_buf fatal: fd=%d, f->fd=%d, f->len=%d f->errno=%d\n", fd, f->fd, f->len, f->saved_errno); } if (size < len) { comerrno(EX_BAD, "unexpected short read-attempt in faio_get_buf. size = %d, len = %d\n", size, len); } if (len < 0) errno = f->saved_errno; sp->gets++; *bpp = f->bufp; f->owner = owner_faio; return len;}EXPORT voidfifo_stats(){ if (sp == NULL) /* We might not use a FIFO */ return; errmsgno(EX_BAD, "fifo had %ld puts and %ld gets.\n", sp->puts, sp->gets); errmsgno(EX_BAD, "fifo was %ld times empty and %ld times full, min fill was %ld%%.\n", sp->empty, sp->full, (100L*sp->cont_low)/faio_buffers);}EXPORT intfifo_percent(addone) BOOL addone;{ int percent; if (buflen == 0L) return (-1); if (sp->done) return (100); percent = (100*(sp->puts + 1 - sp->gets)/faio_buffers); if (percent > 100) return (100); return (percent);}#else /* FIFO */#include <standard.h>#include <sys/types.h>#include <utypes.h>#include "cdrecord.h"EXPORT void init_fifo __PR((long));EXPORT BOOL init_faio __PR((int tracks, track_t *track, int));EXPORT BOOL await_faio __PR((void));EXPORT void kill_faio __PR((void));EXPORT int wait_faio __PR((void));EXPORT int faio_read_buf __PR((int f, char *bp, int size));EXPORT int faio_get_buf __PR((int f, char **bpp, int size));EXPORT void fifo_stats __PR((void));EXPORT int fifo_percent __PR((BOOL addone));EXPORT voidinit_fifo(fs) long fs;{ errmsgno(EX_BAD, "Fifo not supported.\n");}EXPORT BOOLinit_faio(tracks, track, bufsize) int tracks; track_t *track; int bufsize;{ return (FALSE);}EXPORT BOOLawait_faio(){ return (TRUE);}EXPORT voidkill_faio(){}EXPORT intwait_faio(){ return (0);}EXPORT intfaio_read_buf(fd, bp, size) int fd; char *bp; int size;{ return (0);}EXPORT intfaio_get_buf(fd, bpp, size) int fd; char **bpp; int size;{ return (0);}EXPORT voidfifo_stats(){}EXPORT intfifo_percent(addone) BOOL addone;{ return (-1);}#endif /* FIFO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -