From d9e056c3ac2f7bc14e0d1b18452f367b7edf2f62 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 24 Dec 2007 14:21:23 +0000 Subject: [PATCH] Implemented burn_source.cancel() in a binary backwards compatible way --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/file.c | 180 +++++------------------------------- libburn/libburn.h | 28 ++++++ libburn/sector.c | 7 +- libburn/source.c | 14 ++- libburn/source.h | 2 + libburn/write.c | 92 ++++-------------- 7 files changed, 88 insertions(+), 237 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 22dbba4..aa9031c 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.12.07.185206" +#define Cdrskin_timestamP "2007.12.24.141959" diff --git a/libburn/file.c b/libburn/file.c index 2c0b53b..ffa61fd 100644 --- a/libburn/file.c +++ b/libburn/file.c @@ -188,115 +188,8 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size) } -/* ts A70930 */ -/* ----------------------------- fifo ---------------------------- */ - -/* The fifo mechanism consists of a burn_source proxy which is here, - a thread management team which is located in async.c, - and a synchronous shoveller which is here. -*/ - -/* fifo_ng has a ringbuffer and runs in a thread. og is on its way out. */ -#define Libburn_fifo_nG 1 - -#ifndef Libburn_fifo_nG - -static int fifo_read(struct burn_source *source, - unsigned char *buffer, - int size) -{ - struct burn_source_fifo *fs = source->data; - int ret; - - if (fs->is_started == 0) { - ret = burn_fifo_start(source, 0); - if (ret <= 0) { - libdax_msgs_submit(libdax_messenger, -1, 0x00020152, - LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, - "Cannot start fifo thread", 0, 0); - return -1; - } - fs->is_started = 1; - } - if (size == 0) - return 0; - - ret = read_full_buffer(fs->outlet[0], buffer, size); - if (ret > 0) - fs->out_counter += ret; - return ret; -} - - -static off_t fifo_get_size(struct burn_source *source) -{ - struct burn_source_fifo *fs = source->data; - - return fs->inp->get_size(fs->inp); -} - - -static int fifo_set_size(struct burn_source *source, off_t size) -{ - struct burn_source_fifo *fs = source->data; - - return fs->inp->set_size(fs->inp, size); -} - - -static void fifo_free(struct burn_source *source) -{ - struct burn_source_fifo *fs = source->data; - - if (fs->outlet[1] >= 0) - close(fs->outlet[1]); - free(fs); -} - - -int burn_fifo_source_shoveller_og(struct burn_source *source, int flag) -{ - struct burn_source_fifo *fs = source->data; - int ret; - - fs->thread_pid = getpid(); - fs->thread_pid_valid = 1; - - while (1) { - ret = fs->inp->read(fs->inp, (unsigned char *) fs->buf, - fs->chunksize); - if (ret > 0) - fs->in_counter += ret; - else if (ret == 0) - break; /* EOF */ - else { - libdax_msgs_submit(libdax_messenger, -1, 0x00020153, - LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, - "Read error on fifo input", errno, 0); - break; - } - ret = write(fs->outlet[1], fs->buf, ret); - if (ret == -1) { - /* >>> write error */; - break; - } - } - - /* >>> check and destroy ring buffer */; - free(fs->buf); - fs->buf = NULL; - - if (fs->outlet[1] >= 0) - close(fs->outlet[1]); - fs->outlet[1] = -1; - return (ret >= 0); -} - -#endif /* Libburn_fifo_nG */ - - /* ts A71003 */ -/* ----------------------------- fifo ng ------------------------- */ +/* ------------------------------ fifo --------------------------- */ /* The fifo mechanism consists of a burn_source proxy which is here, a thread management team which is located in async.c, @@ -311,7 +204,7 @@ static int fifo_sleep(int flag) } -static int fifo_read_ng(struct burn_source *source, +static int fifo_read(struct burn_source *source, unsigned char *buffer, int size) { @@ -341,7 +234,7 @@ static int fifo_read_ng(struct burn_source *source, /* This needs no mutex because each volatile variable has one thread which may write and the other which only reads and is aware of volatility. - The feeder of the ringbuffer is in burn_fifo_source_shoveller_ng(). + The feeder of the ringbuffer is in burn_fifo_source_shoveller(). */ todo = size; bufsize = fs->chunksize * fs->chunks; @@ -394,7 +287,7 @@ static int fifo_read_ng(struct burn_source *source, } -static off_t fifo_get_size_ng(struct burn_source *source) +static off_t fifo_get_size(struct burn_source *source) { struct burn_source_fifo *fs = source->data; @@ -402,7 +295,7 @@ static off_t fifo_get_size_ng(struct burn_source *source) } -static int fifo_set_size_ng(struct burn_source *source, off_t size) +static int fifo_set_size(struct burn_source *source, off_t size) { struct burn_source_fifo *fs = source->data; @@ -410,7 +303,7 @@ static int fifo_set_size_ng(struct burn_source *source, off_t size) } -static void fifo_free_ng(struct burn_source *source) +static void fifo_free(struct burn_source *source) { struct burn_source_fifo *fs = source->data; @@ -422,7 +315,7 @@ static void fifo_free_ng(struct burn_source *source) } -int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag) +int burn_fifo_source_shoveller(struct burn_source *source, int flag) { struct burn_source_fifo *fs = source->data; int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes; @@ -469,8 +362,12 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag) } /* Obtain next chunk */ - ret = fs->inp->read(fs->inp, (unsigned char *) bufpt, - fs->chunksize); + if (fs->inp->read != NULL) + ret = fs->inp->read(fs->inp, + (unsigned char *) bufpt, fs->chunksize); + else + ret = fs->inp->read_xt( fs->inp, + (unsigned char *) bufpt, fs->chunksize); if (ret > 0) fs->in_counter += ret; else if (ret == 0) @@ -537,15 +434,12 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag) } -#define Libburn_fifo_nG 1 - -int burn_fifo_source_shoveller(struct burn_source *source, int flag) +int burn_fifo_cancel(struct burn_source *source) { -#ifndef Libburn_fifo_nG - return burn_fifo_source_shoveller_og(source, flag); -#else - return burn_fifo_source_shoveller_ng(source, flag); -#endif + struct burn_source_fifo *fs = source->data; + + burn_source_cancel(fs->inp); + return(1); } @@ -554,9 +448,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp, { struct burn_source_fifo *fs; struct burn_source *src; -#ifndef Libburn_fifo_nG - int ret, outlet[2]; -#endif if (((double) chunksize) * ((double) chunks) > 1024.0*1024.0*1024.0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020155, @@ -570,16 +461,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp, "Desired fifo buffer too small", 0, 0); return NULL; } - -#ifndef Libburn_fifo_nG - outlet[0] = outlet[1] = -1; - ret = pipe(outlet); - if (ret == -1) { - /* >>> error on pipe creation */; - return NULL; - } -#endif /* ! Libburn_fifo_nG */ - fs = malloc(sizeof(struct burn_source_fifo)); if (fs == NULL) return NULL; @@ -587,12 +468,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp, fs->thread_pid = 0; fs->thread_pid_valid = 0; fs->inp = NULL; /* set later */ - -#ifndef Libburn_fifo_nG - fs->outlet[0] = outlet[0]; - fs->outlet[1] = outlet[1]; -#endif - fs->chunksize = chunksize; fs->chunks = chunks; fs->buf = NULL; @@ -607,23 +482,15 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp, free((char *) fs); return NULL; } - -#ifndef Libburn_fifo_nG - src->read = fifo_read; + src->read = NULL; src->read_sub = NULL; src->get_size = fifo_get_size; src->set_size = fifo_set_size; src->free_data = fifo_free; -#else /* Libburn_fifo_nG */ - src->read = fifo_read_ng; - src->read_sub = NULL; - src->get_size = fifo_get_size_ng; - src->set_size = fifo_set_size_ng; - src->free_data = fifo_free_ng; -#endif /* ! Libburn_fifo_nG */ - src->data = fs; - + src->version= 1; + src->read_xt = fifo_read; + src->cancel= burn_fifo_cancel; fs->inp = inp; inp->refcount++; /* make sure inp lives longer than src */ @@ -644,7 +511,7 @@ int burn_fifo_inquire_status(struct burn_source *source, *status_text = NULL; *size = 0; - if (source->free_data != fifo_free_ng) { + if (source->free_data != fifo_free) { libdax_msgs_submit(libdax_messenger, -1, 0x00020157, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "burn_source is not a fifo object", 0, 0); @@ -673,4 +540,3 @@ int burn_fifo_inquire_status(struct burn_source *source, return ret; } - diff --git a/libburn/libburn.h b/libburn/libburn.h index 3e14e3c..e9a1b5d 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -376,6 +376,11 @@ struct burn_source { libburn will read a single sector by each call to (*read). The size of a sector depends on BURN_MODE_*. The known range is 2048 to 2352. + + IMPORTANT: + If this function pointer is NULL, then the struct burn_source is of + version >= 1 and the job of .(*read)() is done by .(*read_xt)(). + See below, member .version. */ int (*read)(struct burn_source *, unsigned char *buffer, int size); @@ -442,6 +447,29 @@ struct burn_source { */ void *data; + + /* ts A71222 : Supposed to be binary backwards compatible extension. */ + + /** Valid only if above member .(*read)() is NULL. This indicates a + version of struct burn_source younger than 0. + From then on, member .version tells which further members exist + in the memory layout of struct burn_source. libburn will only touch + those announced extensions. + + Versions: + 0 has .(*read)() != NULL, not even .version is present. + 1 has .version, .(*read_xt)(), .(*cancel)() + */ + int version; + + /** This substitutes for (*read)() in versions above 0. */ + int (*read_xt)(struct burn_source *, unsigned char *buffer, int size); + + /** Informs the burn_source that the consumer of data prematurely + ended reading. This call may or may not be issued by libburn + before (*free_data)() is called. + */ + int (*cancel)(struct burn_source *source); }; diff --git a/libburn/sector.c b/libburn/sector.c index 3bf339b..3551314 100644 --- a/libburn/sector.c +++ b/libburn/sector.c @@ -123,7 +123,12 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data) /* Next we use source data */ curr = valid; if (!track->eos) { - valid = track->source->read(track->source, data + curr, count - curr); + if (track->source->read != NULL) + valid = track->source->read(track->source, + data + curr, count - curr); + else + valid = track->source->read_xt(track->source, + data + curr, count - curr); } else valid = 0; if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */ diff --git a/libburn/source.c b/libburn/source.c index b255a10..17ecee4 100644 --- a/libburn/source.c +++ b/libburn/source.c @@ -18,8 +18,6 @@ void burn_source_free(struct burn_source *src) enum burn_source_status burn_track_set_source(struct burn_track *t, struct burn_source *s) { - if (!s->read) - return BURN_SOURCE_FAILED; s->refcount++; t->source = s; @@ -43,3 +41,15 @@ struct burn_source *burn_source_new(void) out->refcount = 1; return out; } + + +/* ts A71223 */ +int burn_source_cancel(struct burn_source *src) +{ + if(src->read == NULL) + if(src->version > 0) + if(src->cancel != NULL) + src->cancel(src); + return 1; +} + diff --git a/libburn/source.h b/libburn/source.h index e0a69aa..1f31527 100644 --- a/libburn/source.h +++ b/libburn/source.h @@ -5,4 +5,6 @@ struct burn_source *burn_source_new(void); +int burn_source_cancel(struct burn_source *src); + #endif /*__SOURCE*/ diff --git a/libburn/write.c b/libburn/write.c index 5da9f3c..e6715fd 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -43,6 +43,7 @@ #include "write.h" #include "options.h" #include "structure.h" +#include "source.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; @@ -836,6 +837,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, /* ts A61103 */ ret = 1; ex:; + if (d->cancel) + burn_source_cancel(t->source); if (o->write_type == BURN_WRITE_TAO) { /* ts A71002 */ @@ -1273,6 +1276,8 @@ int burn_dvd_write_track(struct burn_write_opts *o, } ret = 1; ex:; + if (d->cancel) + burn_source_cancel(t->source); if (!is_flushed) d->sync_cache(d); /* burn_write_flush() was not called */ return ret; @@ -1693,7 +1698,11 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize, int count= 0, todo; for(todo = bufsize; todo > 0; todo -= count) { - count = source->read(source, + if(source->read!=NULL) + count = source->read(source, + (unsigned char *) (buf + (bufsize - todo)), todo); + else + count = source->read_xt(source, (unsigned char *) (buf + (bufsize - todo)), todo); if (count <= 0) break; @@ -1718,16 +1727,6 @@ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d, } -/* ts A70911 - If defined this makes stdio run on top of sector_data() rather than - own stdio read and write functions. The MMC function pointers d->write() - and d->sync_cache() get replaced by stdio substitutes. -*/ -#define Libburn_stdio_track_by_sector_datA 1 - - -#ifdef Libburn_stdio_track_by_sector_datA - /* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */ int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf) { @@ -1849,9 +1848,6 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time, } -#endif /* Libburn_stdio_track_by_sector_datA */ - - /* ts A70904 */ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum, int flag) @@ -1860,14 +1856,9 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, struct burn_track *t = s->track[tnum]; struct burn_drive *d = o->drive; char buf[16*2048]; -#ifdef Libburn_stdio_track_by_sector_datA int i, prev_sync_sector = 0; struct buffer *out = d->buffer; struct timeval prev_time; -#else - int eof_seen = 0; - off_t t_size, w_count; -#endif bufsize = sizeof(buf); fd = d->stdio_fd; @@ -1876,8 +1867,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, burn_disc_init_track_status(o, s, tnum, sectors); open_ended = burn_track_is_open_ended(t); -#ifdef Libburn_stdio_track_by_sector_datA - /* attach stdio emulators for mmc_*() functions */ if (o->simulate) d->write = burn_stdio_mmc_dummy_write; @@ -1889,7 +1878,7 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, for (i = 0; open_ended || i < sectors; i++) { /* transact a (CD sized) sector */ if (!sector_data(o, t, 0)) - return 0; + {ret= 0; goto ex;} if (open_ended) { d->progress.sectors = sectors = d->progress.sector; if (burn_track_is_data_done(t)) @@ -1912,60 +1901,11 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, out->bytes = o->obs; } ret = burn_write_flush(o, t); - -#else /* Libburn_stdio_track_by_sector_datA */ - - t_size = t->source->get_size(t->source); - - /* >>> write t->offset zeros */; - - for(w_count = 0; w_count < t_size || open_ended; w_count += ret) { - - - if (t_size - w_count < bufsize && ! open_ended) - - /* >>> what about final sector padding ? */ - - bufsize = t_size - w_count; - if (eof_seen) - ret = 0; - else - ret = burn_stdio_read_source(t->source, buf, - bufsize, o, 0); - if (ret < 0) - return ret; - if (ret == 0 && open_ended) - break; - if (ret < bufsize && !open_ended) { - memset(buf + ret, 0, bufsize - ret); - eof_seen = 1; - ret = bufsize; - } - t->sourcecount += ret; - if (!o->simulate) - ret = burn_stdio_write(fd, buf, ret, d, 0); - if (ret <= 0) - return ret; - - d->progress.sector = (w_count + (off_t) ret) / (off_t) 2048; - if (open_ended) - d->progress.sectors = d->progress.sector; - t->writecount += ret; - t->written_sectors = t->writecount / 2048; - - /* Flush to physical device after each full MB */ - if (d->progress.sector - prev_sync_sector >= 512) { - prev_sync_sector = d->progress.sector; - if (!o->simulate) - burn_stdio_sync_cache(fd, d, 1); - } - } - - /* >>> write t->tail zeros */; - -#endif - - return 1; + ret= 1; +ex:; + if (d->cancel) + burn_source_cancel(t->source); + return ret; }