diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index a64d7e0..8e0050c 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2010.03.04.180102" +#define Cdrskin_timestamP "2010.03.05.090948" diff --git a/libburn/async.c b/libburn/async.c index d13e057..e520cf3 100644 --- a/libburn/async.c +++ b/libburn/async.c @@ -40,6 +40,7 @@ #include #include #include +#include /* #include @@ -534,8 +535,22 @@ no_non_default_bd_re:; static void *write_disc_worker_func(struct w_list *w) { struct burn_drive *d = w->u.write.drive; + char msg[80]; + +#define Libburn_protect_write_threaD 1 + +#ifdef Libburn_protect_write_threaD + sigset_t sigset, oldset; + + /* Protect write thread from being interrupted by external signals */ + sigfillset(&sigset); + sigdelset(&sigset, SIGSEGV); + sigdelset(&sigset, SIGILL); + pthread_sigmask(SIG_SETMASK, &sigset, &oldset); +#endif /* Libburn_protect_write_threaD */ d->thread_pid = getpid(); + d->thread_tid = pthread_self(); d->thread_pid_valid= 1; burn_disc_write_sync(w->u.write.opts, w->u.write.disc); d->thread_pid_valid= 0; @@ -545,7 +560,18 @@ static void *write_disc_worker_func(struct w_list *w) */ burn_write_opts_free(w->u.write.opts); + sprintf(msg, "Write thread on drive %d ended", d->global_index); + libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + +#ifdef Libburn_protect_write_threaD + /* (just in case it would not end with all signals blocked) */ + pthread_sigmask(SIG_SETMASK, &oldset, NULL); +#endif /* Libburn_protect_write_threaD */ + remove_worker(pthread_self()); + d->busy = BURN_DRIVE_IDLE; return NULL; } @@ -653,6 +679,18 @@ int burn_fifo_start(struct burn_source *source, int flag) struct fifo_opts o; struct burn_source_fifo *fs = source->data; +#define Libburn_protect_fifo_threaD 1 + +#ifdef Libburn_protect_fifo_threaD + sigset_t sigset, oldset; + + /* Protect write thread from being interrupted by external signals */ + sigfillset(&sigset); + sigdelset(&sigset, SIGSEGV); + sigdelset(&sigset, SIGILL); + pthread_sigmask(SIG_SETMASK, &sigset, &oldset); +#endif /* Libburn_protect_fifo_threaD */ + fs->is_started = -1; /* create and set up ring buffer */; @@ -668,6 +706,12 @@ int burn_fifo_start(struct burn_source *source, int flag) add_worker(Burnworker_type_fifO, NULL, (WorkerFunc) fifo_worker_func, &o); fs->is_started = 1; + +#ifdef Libburn_protect_fifo_threaD + /* (just in case it would not end with all signals blocked) */ + pthread_sigmask(SIG_SETMASK, &oldset, NULL); +#endif /* Libburn_protect_fifo_threaD */ + return 1; } diff --git a/libburn/drive.c b/libburn/drive.c index d11418a..f274e3e 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -376,6 +376,7 @@ struct burn_drive *burn_drive_register(struct burn_drive *d) d->busy = BURN_DRIVE_IDLE; d->thread_pid = 0; d->thread_pid_valid = 0; + memset(&(d->thread_tid), 0, sizeof(d->thread_tid)); d->toc_entries = 0; d->toc_entry = NULL; d->disc = NULL; @@ -815,10 +816,22 @@ int burn_disc_erasable(struct burn_drive *d) enum burn_drive_status burn_drive_get_status(struct burn_drive *d, struct burn_progress *p) { + /* --- Part of asynchronous signal handling --- */ + /* This frequently used call may be used to react on messages from + the libburn built-in signal handler. + */ + + /* ts B00225 : + If aborting with action 2: + catch control thread after it returned from signal handler. + Let it run burn_abort(4440,...) + */ + burn_init_catch_on_abort(0); + /* ts A70928 : inform control thread of signal in sub-threads */ - if (burn_global_abort_level > 0) + if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 0) burn_global_abort_level++; - if (burn_global_abort_level > 5) { + if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 5) { if (burn_global_signal_handler == NULL) kill(getpid(), burn_global_abort_signum); else @@ -828,6 +841,9 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d, burn_global_abort_level = -1; } + /* --- End of asynchronous signal handling --- */ + + if (p != NULL) { memcpy(p, &(d->progress), sizeof(struct burn_progress)); /* TODO: add mutex */ @@ -849,9 +865,13 @@ int burn_drive_set_stream_recording(struct burn_drive *d, int recmode, void burn_drive_cancel(struct burn_drive *d) { +/* ts B00225 : these mutexes are unnecessary because "= 1" is atomar. pthread_mutex_lock(&d->access_lock); +*/ d->cancel = 1; +/* pthread_mutex_unlock(&d->access_lock); +*/ } /* ts A61007 : defunct because unused */ @@ -1868,17 +1888,12 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed) } -/** Abort any running drive operation and finish libburn. - @param patience Maximum number of seconds to wait for drives to finish - @param pacifier_func Function to produce appeasing messages. See - burn_abort_pacifier() for an example. - @return 1 ok, all went well - 0 had to leave a drive in unclean state - <0 severe error, do no use libburn again +/* ts B00226 : Outsourced backend of burn_abort() + @param flag bit0= do not call burn_finish() */ -int burn_abort(int patience, +int burn_abort_5(int patience, int (*pacifier_func)(void *handle, int patience, int elapsed), - void *handle) + void *handle, int elapsed, int flag) { int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1; unsigned long wait_grain= 100000; @@ -1888,7 +1903,11 @@ int burn_abort(int patience, time_t stdio_patience = 3; #endif + +fprintf(stderr, "libburn_EXPERIMENTAL: burn_abort_5(%d,%d)\n", patience, flag); + current_time = start_time = pacifier_time = time(0); + start_time -= elapsed; end_time = start_time + patience; /* >>> ts A71002 : are there any threads at work ? @@ -1935,6 +1954,9 @@ int burn_abort(int patience, } if(occup <= 10) { + if (drive_array[i].drive_role != 1) + /* occup == -1 comes early */ + usleep(1000000); burn_drive_forget(&(drive_array[i]), 1); } else if(occup <= 100) { if(first_round) @@ -1959,12 +1981,95 @@ int burn_abort(int patience, pacifier_time = current_time; } } - if (patience > 0) + if (!(flag & 1)) burn_finish(); return(still_not_done == 0); } +#ifdef NIX + +/* <<< did not help. Is on its way out */ +/* ts B00226 */ +/* Wait for the most delicate drive states to end +*/ +int burn_abort_write(int patience, + int (*pacifier_func)(void *handle, int patience, int elapsed), + void *handle) +{ + int ret, i, still_not_done= 1, pacifier_off= 0; + unsigned long wait_grain= 100000; + time_t start_time, current_time, pacifier_time, end_time; + struct burn_drive *d; + +fprintf(stderr, "libburn_EXPERIMENTAL: burn_abort_write\n"); + + current_time = start_time = pacifier_time = time(0); + end_time = start_time + patience; + + while(current_time < end_time || patience <= 0) { + still_not_done = 0; + + for(i = 0; i < drivetop + 1; i++) { + d = &(drive_array[i]); + if(d->global_index < 0) + continue; + if(d->busy != BURN_DRIVE_WRITING && + d->busy != BURN_DRIVE_WRITING_LEADIN && + d->busy != BURN_DRIVE_WRITING_LEADOUT && + d->busy != BURN_DRIVE_WRITING_PREGAP && + d->busy != BURN_DRIVE_CLOSING_TRACK && + d->busy != BURN_DRIVE_CLOSING_SESSION) + continue; + still_not_done = 1; + } + + if(still_not_done == 0 || patience <= 0) + break; + usleep(wait_grain); + current_time = time(0); + if(current_time>pacifier_time) { + if(pacifier_func != NULL && !pacifier_off) { + ret = (*pacifier_func)(handle, patience, + current_time - start_time); + pacifier_off = (ret <= 0); + } + pacifier_time = current_time; + } + } + if (current_time - start_time > patience - 3) + patience = current_time - start_time + 3; + ret = burn_abort_5(patience, pacifier_func, handle, + current_time - start_time, 0); + return ret; +} + +#endif /* NIX */ + + +/** Abort any running drive operation and finish libburn. + @param patience Maximum number of seconds to wait for drives to finish + @param pacifier_func Function to produce appeasing messages. See + burn_abort_pacifier() for an example. + @return 1 ok, all went well + 0 had to leave a drive in unclean state + <0 severe error, do no use libburn again +*/ +int burn_abort(int patience, + int (*pacifier_func)(void *handle, int patience, int elapsed), + void *handle) +{ + int ret, flg = 0; + + if (patience < 0) { + patience = 0; + flg |= 1; + } + ret = burn_abort_5(patience, pacifier_func, handle, 0, flg); + return ret; +} + + /* ts A61020 API function */ int burn_drive_get_start_end_lba(struct burn_drive *d, int *start_lba, int *end_lba, int flag) @@ -2698,7 +2803,8 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2) } -int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid) +int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid, + pthread_t tid) { int i; @@ -2710,7 +2816,8 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid) */ if (drive_array[i].thread_pid_valid && - drive_array[i].thread_pid == pid) { + drive_array[i].thread_pid == pid && + pthread_equal(drive_array[i].thread_tid, tid)) { *d = &(drive_array[i]); return 1; } diff --git a/libburn/drive.h b/libburn/drive.h index 357ca26..e043e5c 100644 --- a/libburn/drive.h +++ b/libburn/drive.h @@ -127,8 +127,9 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc, int burn_drive__fd_from_special_adr(char *adr); -/* ts A70929 : Find the drive which is being worked on by pid */ -int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid); +/* ts A70929 : Find the drive which is being worked on by pid , tid */ +int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid, + pthread_t tid); /* ts A51221 - A80731 : Whitelist inquiry functions */ @@ -140,5 +141,20 @@ char *burn_drive_whitelist_item(int idx, int flag); /* ts A80801 */ int burn_drive_is_listed(char *path, struct burn_drive **found, int flag); +#ifdef NIX +/* <<< did not help. Is on its way out */ +/* ts B00226 */ +int burn_abort_write(int patience, + int (*pacifier_func)(void *handle, int patience, int elapsed), + void *handle); +#endif /* NIX */ + +/* ts B00226 : Outsourced backend of burn_abort() + @param elapsed to be subtracted from start time + @param flag bit0= do not shutdown the library +*/ +int burn_abort_5(int patience, + int (*pacifier_func)(void *handle, int patience, int elapsed), + void *handle, int elapsed, int flag); #endif /* __DRIVE */ diff --git a/libburn/init.c b/libburn/init.c index f3c35b4..9f5ca2d 100644 --- a/libburn/init.c +++ b/libburn/init.c @@ -15,6 +15,7 @@ #include #include #include +#include /* ts A70928 : init.h is for others, not for init .c #include "init.h" @@ -80,10 +81,13 @@ static char sg_initialize_msg[1024] = {""}; /* Parameters for builtin abort handler */ static char abort_message_prefix[81] = {"libburn : "}; static pid_t abort_control_pid= 0; +static pthread_t abort_control_thread; volatile int burn_global_abort_level= 0; int burn_global_abort_signum= 0; void *burn_global_signal_handle = NULL; burn_abort_handler_t burn_global_signal_handler = NULL; +int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */ +volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */ /* ts A70223 : wether implemented untested profiles are supported */ @@ -329,23 +333,75 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag) return ret; } +/* ts B00224 */ +char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80]) +{ + int i, l; + + sprintf(text, "[%d,", getpid()); + l= strlen(text); + for(i= 0; i < sizeof(pthread_t) && 2 * i < 80 - l - 3; i++) + sprintf(text + l + 2 * i, + "%2.2X", ((unsigned char *) &tid)[i]); + + sprintf(text + l + 2 * i, "]"); + return text; +} int burn_builtin_abort_handler(void *handle, int signum, int flag) { #define Libburn_new_thread_signal_handleR 1 /* -#define Libburn_signal_handler_verbouS 1 */ +#define Libburn_signal_handler_verbouS 1 + int ret; struct burn_drive *d; #ifdef Libburn_signal_handler_verbouS - fprintf(stderr, - "libburn_ABORT: pid = %d , abort_control_pid = %d , sig= %d\n", - getpid(), abort_control_pid, signum); + char text[80]; + + fprintf(stderr, "libburn_ABORT: in = %s\n", + burn_util_thread_id(getpid(), pthread_self(), text)); + fprintf(stderr, "libburn_ABORT: ctrl = %s\n", + burn_util_thread_id(abort_control_pid, abort_control_thread, + text)); + if (burn_global_signal_handler == burn_builtin_abort_handler) + fprintf(stderr, "libburn_ABORT: signal action = %d\n", + burn_builtin_signal_action); + + /* >>> find writing drives and report their tid + fprintf(stderr, "libburn_ABORT: wrt = %s\n", + burn_util_thread_id(0, burn_write_thread_id, text)); + fprintf(stderr, "libburn_ABORT: sig= %d\n", signum); + */ #endif + burn_builtin_triggered_action = burn_builtin_signal_action; + burn_global_abort_level = -1; + + if (burn_builtin_signal_action > 1) { + Cleanup_set_handlers(NULL, NULL, 2); + if (burn_builtin_signal_action == 4) + return -2; + fprintf(stderr,"%sABORT : Trying to shut down busy drives\n", + abort_message_prefix); + fprintf(stderr, + "%sABORT : Wait the normal burning time before any kill -9\n", + abort_message_prefix); + burn_abort_5(0, burn_abort_pacifier, abort_message_prefix, + 0, 1); + libdax_msgs_submit(libdax_messenger, -1, 0x00020177, + LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH, + "Urged drive worker threads to do emergency halt", + 0, 0); + return -2; + } + + + /* ---- old deprecated stuck-in-abort-handler loop ---- */ + /* ts A70928: Must be quick. Allowed to coincide with other thread and to share the increment with that one. It must not decrease, though, and @@ -358,7 +414,8 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag) #ifdef Libburn_new_thread_signal_handleR - ret = burn_drive_find_by_thread_pid(&d, getpid()); + ret = burn_drive_find_by_thread_pid(&d, getpid(), + pthread_self()); if (ret > 0 && d->busy == BURN_DRIVE_WRITING) { /* This is an active writer thread */ @@ -398,13 +455,13 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag) } burn_global_abort_level = -1; Cleanup_set_handlers(NULL, NULL, 2); + fprintf(stderr,"%sABORT : Trying to shut down drive and library\n", abort_message_prefix); fprintf(stderr, "%sABORT : Wait the normal burning time before any kill -9\n", abort_message_prefix); close(0); /* somehow stdin as input blocks abort until EOF */ - burn_abort(4440, burn_abort_pacifier, abort_message_prefix); fprintf(stderr, @@ -414,8 +471,10 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag) return(1); } + +/* ts A61002 : API */ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, - int mode) + int mode) { /* @@ -436,12 +495,56 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, sizeof(abort_message_prefix)-1); abort_message_prefix[sizeof(abort_message_prefix)-1] = 0; abort_control_pid = getpid(); - Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4); + abort_control_thread = pthread_self(); + burn_builtin_signal_action = (mode >> 4) & 15; + if((mode & 11) != 0) + burn_builtin_signal_action = 0; + if(burn_builtin_signal_action > 1) + burn_builtin_triggered_action = 0; + if(burn_builtin_signal_action == 0) + burn_builtin_signal_action = 1; + +fprintf(stderr, "libburn_EXPERIMENTAL: mode = %d , burn_builtin_signal_action = %d\n", +mode, burn_builtin_signal_action); + + Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, + (mode & 15) | 4); burn_global_signal_handle = handle; burn_global_signal_handler = handler; } +/* ts B00304 : API */ +int burn_is_aborting(int flag) +{ + return burn_builtin_triggered_action; +} + + +/* ts B00225 */ +/* @return 0= no abort action 2 pending , 1= not control thread +*/ +int burn_init_catch_on_abort(int flag) +{ + if (burn_builtin_triggered_action != 2) + return 0; + if (abort_control_pid != getpid() || + abort_control_thread != pthread_self()) + return 1; + +#ifdef NIX + burn_abort_write(4440, burn_abort_pacifier, abort_message_prefix); +#else + burn_abort(4440, burn_abort_pacifier, abort_message_prefix); +#endif + + fprintf(stderr, + "\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n", + abort_message_prefix); + exit(1); +} + + /* ts A70223 : API */ void burn_allow_untested_profiles(int yes) { diff --git a/libburn/init.h b/libburn/init.h index ba2fb4f..9d09818 100644 --- a/libburn/init.h +++ b/libburn/init.h @@ -17,5 +17,15 @@ extern int burn_global_abort_signum; extern void *burn_global_signal_handle; extern burn_abort_handler_t burn_global_signal_handler; +extern int burn_builtin_signal_action; /* burn_set_signal_handling() */ +extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */ + + +/* ts B00225 */ +/* @return 0= no abort pending , 1= not control thread , + -1= surprisingly burn_abort returned +*/ +int burn_init_catch_on_abort(int flag); + #endif /* BURN__INIT_H */ diff --git a/libburn/libburn.h b/libburn/libburn.h index 9fde0d3..ea22ad1 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -736,17 +736,22 @@ void burn_finish(void); /* ts A61002 */ -/** Abort any running drive operation and finally call burn_finish(). - You MUST calm down the busy drive if an aborting event occurs during a +/** Abort any running drive operation and eventually call burn_finish(). + + You MUST shut down the busy drives if an aborting event occurs during a burn run. For that you may call this function either from your own signal - handling code or indirectly by activating the builtin signal handling: + handling code or indirectly by activating the built-in signal handling: burn_set_signal_handling("my_app_name : ", NULL, 0); - Else you may eventually call burn_drive_cancel() on the active drive and - wait for it to assume state BURN_DRIVE_IDLE. - @param patience Maximum number of seconds to wait for drives to finish + Else you may eventually call burn_drive_cancel() on the active drives and + wait for them to assume state BURN_DRIVE_IDLE. + @param patience Maximum number of seconds to wait for drives to + finish. + @since 0.7.8 : + If this is -1, then only the cancel operations will + be performed and no burn_finish() will happen. @param pacifier_func If not NULL: a function to produce appeasing messages. See burn_abort_pacifier() for an example. - @param handle Opaque handle to be used with pacifier_func + @param handle Opaque handle to be used with pacifier_func @return 1 ok, all went well 0 had to leave a drive in unclean state <0 severe error, do no use libburn again @@ -2784,30 +2789,78 @@ int burn_set_messenger(void *messenger); /* ts A61002 */ /* @since 0.2.6 */ -/** The prototype of a handler function suitable for burn_set_abort_handling(). +/** The prototype of a handler function suitable for burn_set_signal_handling() Such a function has to return -2 if it does not want the process to exit with value 1. */ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag); -/** Control builtin signal handling. See also burn_abort(). +/** Control built-in signal handling. Either by setting an own handler or + by activating the built-in signal handler. + + A function parameter handle of NULL activates the built-in abort handler. + Depending on mode it may cancel all drive operations, wait for all drives + to become idle, exit(1). It may also prepare function + burn_drive_get_status() for waiting and performing exit(1). + If text is not NULL then it is used as prefix for pacifier messages of + burn_abort_pacifier(). + Before version 0.7.8 only action 0 was available. I.e. the built-in handler + waited for the drives to become idle and then performed exit(1) directly. + But FreeBSD 8.0 sometimes pauses the other threads until the signal handler + returns. + The new actions try to avoid this deadlock. It is advised to use action 3 + burn_set_signal_handling(text, NULL, 48); + and call burn_is_aborting(0) frequently. If it replies 1, then call + burn_abort() and exit(1). @param handle Opaque handle eventually pointing to an application provided memory object @param handler A function to be called on signals. It will get handle as - argument. It should finally call burn_abort(). See there. - @param mode : 0 call handler(handle, signum, 0) on nearly all signals - 1 enable system default reaction on all signals - 2 try to ignore nearly all signals - 10 like mode 2 but handle SIGABRT like with mode 0 - Arguments (text, NULL, 0) activate the builtin abort handler. It will - eventually call burn_abort() and then perform exit(1). If text is not NULL - then it is used as prefix for pacifier messages of burn_abort_pacifier(). + argument. flag will be 0. + It should finally call burn_abort(). See there. + @param mode : bit0 - bit3: + Receiving signals: + 0 Call handler(handle, signum, 0) on nearly all signals + 1 Enable system default reaction on all signals + 2 Try to ignore nearly all signals + 10 like mode 2 but handle SIGABRT like with mode 0 + bit4 - bit7: With handler == NULL : + Action of built-in handler. "control thread" is the one + which called burn_set_signal_handling(). + All actions activate receive mode 2 to ignore further + signals. + 0 Same as 1 (for pre-0.7.8 backward compatibility) + @since 0.7.8 + 1 Catch the control thread in abort handler, call + burn_abort(>0) and finally exit(1). + Does not always work with FreeBSD. + 2 Call burn_abort(-1) and return from handler. When the + control thread calls burn_drive_get_status(), then do + burn_abort(>0) instead, and finally exit(1). + Does not always work with FreeBSD. + 3 Call burn_abort(-1), return from handler. It is duty of + the application to detect a pending abort condition + by calling burn_is_aborting() and to wait for all + drives to become idle. E.g. by calling burn_abort(>0). + 4 Like 3, but without calling burn_abort(-1). Only the + indicator of burn_is_aborting() gets set. @since 0.2.6 */ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, int mode); +/* ts B00304 */ +/* Inquire whether the built-in abort handler was triggered by a signal. + This has to be done to detect pending abort handling if signal handling + was set to the built-in handler and action was set to 2 or 3. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 0 = no abort was triggered + >0 = action that was triggered (action 0 is reported as 1) + @since 0.7.8 +*/ +int burn_is_aborting(int flag); + + /* ts A70811 */ /** Write data in random access mode. The drive must be grabbed successfully before calling this function which @@ -2955,5 +3008,11 @@ BURN_END_DECLS #define Libburn_dummy_probe_write_modeS 1 +/* ts B00225 */ +/* Leave abort handler quickly and catch control thread in + burn_drive_get_status(). +*/ +#define Libburn_signal_handler_return_2 1 + #endif /*LIBBURN_H*/ diff --git a/libburn/libdax_msgs.c b/libburn/libdax_msgs.c index 908730f..99e7fb3 100644 --- a/libburn/libdax_msgs.c +++ b/libburn/libdax_msgs.c @@ -12,6 +12,7 @@ #include #include #include +#include /* Only this single source module is entitled to do this */ #define LIBDAX_MSGS_H_INTERNAL 1 diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 2960aff..061bd7c 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -554,6 +554,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size 0x00020175 (FATAL,HIGH) = Supporting library is too old 0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer + 0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt + 0x00020178 (DEBUG,HIGH) = Write thread ended libdax_audioxtr: diff --git a/libburn/sector.c b/libburn/sector.c index 5a6b272..dc2ac7d 100644 --- a/libburn/sector.c +++ b/libburn/sector.c @@ -31,7 +31,7 @@ extern struct libdax_msgs *libdax_messenger; #ifdef Libburn_log_in_and_out_streaM -/* <<< ts A61031 */ +/* ts A61031 */ #include #include #include @@ -102,7 +102,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data) int valid, shortage, curr, i, tr; #ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ + /* ts A61031 */ static int tee_fd= -1; if(tee_fd==-1) tee_fd= open("/tmp/libburn_sg_readin", @@ -148,7 +148,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data) track->sourcecount += valid; #ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ + /* ts A61031 */ if(tee_fd!=-1 && valid>0) { write(tee_fd, data + curr, valid); } @@ -678,7 +678,7 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub) unsigned char *data; data = get_sector(o, t, t->mode); - if (!data) + if (data == NULL) return 0; /* ts A61010 */ if (convert_data(o, t, t->mode, data) <= 0) diff --git a/libburn/transport.h b/libburn/transport.h index 3a22f12..2b6c4db 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -312,6 +312,8 @@ struct burn_drive /* ts A70929 */ pid_t thread_pid; int thread_pid_valid; + /* ts B00225 */ + pthread_t thread_tid; /* transport functions */ diff --git a/libburn/write.c b/libburn/write.c index cf29ebf..9bdccd7 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -1312,7 +1312,7 @@ static int transact_dvd_chunk(struct burn_write_opts *opts, unsigned char *data = out->data; #ifdef Libburn_log_in_and_out_streaM - /* <<< ts A61031 */ + /* ts A61031 */ static int tee_fd= -1; if(tee_fd==-1) tee_fd= open("/tmp/libburn_sg_readin", @@ -2002,7 +2002,7 @@ ex:; burn_drive_mark_unready(d); burn_drive_inquire_media(d); - d->busy = BURN_DRIVE_IDLE; + /* <<< d->busy = BURN_DRIVE_IDLE; */ return ret; early_failure:; return 0; @@ -2330,7 +2330,7 @@ ex:; /* update media state records */ burn_drive_mark_unready(d); - d->busy = BURN_DRIVE_IDLE; + /* <<< d->busy = BURN_DRIVE_IDLE; */ return ret; } @@ -2567,7 +2567,7 @@ return crap. so we send the command, then ignore the result. burn_drive_inquire_media(d); burn_print(1, "done\n"); - d->busy = BURN_DRIVE_IDLE; + /* <<< d->busy = BURN_DRIVE_IDLE; */ /* ts A61012 : This return was traditionally missing. I suspect this to have caused Cdrskin_eject() failures */ @@ -2582,7 +2582,7 @@ fail_wo_sync:; LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Burn run failed", 0, 0); d->cancel = 1; - d->busy = BURN_DRIVE_IDLE; + /* <<< d->busy = BURN_DRIVE_IDLE; */ ex:; d->do_stream_recording = 0; if (d->buffer != NULL)