New API call Xorriso_fetch_outlists()

This commit is contained in:
Thomas Schmitt 2012-09-11 09:28:05 +00:00
parent b84c80ab11
commit 2a046ed32d
7 changed files with 230 additions and 35 deletions

View File

@ -124,6 +124,7 @@ Xorriso_destroy;
Xorriso_dialog; Xorriso_dialog;
Xorriso_eval_problem_status; Xorriso_eval_problem_status;
Xorriso_execute_option; Xorriso_execute_option;
Xorriso_fetch_outlists;
Xorriso_get_problem_status; Xorriso_get_problem_status;
Xorriso_interpreter; Xorriso_interpreter;
Xorriso_lst_destroy_all; Xorriso_lst_destroy_all;

View File

@ -25,6 +25,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
@ -317,6 +318,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->info_msglists[i]= NULL; m->info_msglists[i]= NULL;
m->msglist_flags[i]= 0; m->msglist_flags[i]= 0;
} }
m->lib_msg_queue_lock_ini= 0;
m->result_msglists_lock_ini= 0;
m->msglist_stackfill= 0; m->msglist_stackfill= 0;
m->status_history_max= Xorriso_status_history_maX; m->status_history_max= Xorriso_status_history_maX;
m->scsi_log= 0; m->scsi_log= 0;
@ -433,6 +436,14 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
if(ret <= 0) if(ret <= 0)
goto failure; goto failure;
Xorriso_preparer_string(m, m->preparer_id, 1); /* avoids library calls */ Xorriso_preparer_string(m, m->preparer_id, 1); /* avoids library calls */
ret= pthread_mutex_init(&(m->lib_msg_queue_lock), NULL);
if(ret != 0)
goto failure;
m->lib_msg_queue_lock_ini= 1;
ret= pthread_mutex_init(&(m->result_msglists_lock), NULL);
if(ret != 0)
goto failure;
m->result_msglists_lock_ini= 1;
if(leafname != NULL) if(leafname != NULL)
free(leafname); free(leafname);
@ -513,7 +524,11 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag)
for(i= 0; i < Xorriso_max_appended_partitionS; i++) for(i= 0; i < Xorriso_max_appended_partitionS; i++)
if(m->appended_partitions[i] != NULL) if(m->appended_partitions[i] != NULL)
free(m->appended_partitions[i]); free(m->appended_partitions[i]);
if(m->lib_msg_queue_lock_ini)
pthread_mutex_destroy(&(m->lib_msg_queue_lock));
if(m->result_msglists_lock_ini)
pthread_mutex_destroy(&(m->result_msglists_lock));
Xorriso_detach_libraries(m, flag&1); Xorriso_detach_libraries(m, flag&1);
free((char *) m); free((char *) m);

View File

@ -23,6 +23,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
@ -469,15 +470,26 @@ cannot:;
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag) int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
{ {
int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled; int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled;
int name_prefix_code; int name_prefix_code, locked= 0, uret;
char severity[80]; char severity[80];
#ifdef Xorriso_with_libjtE #ifdef Xorriso_with_libjtE
char *msg; char *msg;
#endif #endif
if(!xorriso->libs_are_started) if(!xorriso->libs_are_started) {
return(1); ret= 1; goto ex;
}
ret= pthread_mutex_lock(&(xorriso->lib_msg_queue_lock));
if(ret != 0) {
Xorriso_msgs_submit(xorriso, 0,
"Cannot aquire mutex lock for processing library message queues",
errno, "FATAL", 0);
ret= -1; goto ex;
}
locked= 1;
for(pass= 0; pass< 3; pass++) { for(pass= 0; pass< 3; pass++) {
while(1) { while(1) {
tunneled= 0; tunneled= 0;
@ -536,6 +548,17 @@ int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
count); count);
Xorriso_info(xorriso, 0); Xorriso_info(xorriso, 0);
} }
ret= 1;
ex:;
if(locked) {
uret= pthread_mutex_unlock(&(xorriso->lib_msg_queue_lock));
if(uret != 0) {
Xorriso_msgs_submit(xorriso, 0,
"Cannot release mutex lock for processing library message queues",
errno, "FATAL", 0);
ret= -1;
}
}
return(1); return(1);
} }

View File

@ -23,6 +23,8 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <pthread.h>
/* for -charset */ /* for -charset */
#include <iconv.h> #include <iconv.h>
@ -520,6 +522,68 @@ ex:;
} }
static int Xorriso_lock_outlists(struct XorrisO *xorriso, int flag)
{
int ret;
static int complaints= 0, complaint_limit= 5;
ret= pthread_mutex_lock(&(xorriso->result_msglists_lock));
if(ret != 0) {
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_lock() for outlists returns %d\n",
ret);
return(-1);
}
return(1);
}
static int Xorriso_unlock_outlists(struct XorrisO *xorriso, int flag)
{
int ret;
static int complaints= 0, complaint_limit= 5;
ret= pthread_mutex_unlock(&(xorriso->result_msglists_lock));
if(ret != 0) {
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_unlock() for outlists returns %d\n",
ret);
return(0);
}
return(1);
}
static int Xorriso_write_to_msglist(struct XorrisO *xorriso,
struct Xorriso_lsT **xorriso_msglist,
char *text, int flag)
{
int ret;
struct Xorriso_lsT *msglist;
ret= Xorriso_lock_outlists(xorriso, 0);
if(ret <= 0)
return(-1);
msglist= *xorriso_msglist;
ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0);
if(ret <= 0) {
ret= -1; goto ex;
}
if(*xorriso_msglist == NULL)
*xorriso_msglist= msglist;
ret= 1;
ex:;
Xorriso_unlock_outlists(xorriso, 0);
return(ret);
}
int Xorriso_write_to_channel(struct XorrisO *xorriso, int Xorriso_write_to_channel(struct XorrisO *xorriso,
char *in_text, int channel_no, int flag) char *in_text, int channel_no, int flag)
/* /*
@ -534,7 +598,6 @@ bit15= with bit1 to bit3: close depicted log file
int ret= 1, info_redirected= 0, result_redirected= 0; int ret= 1, info_redirected= 0, result_redirected= 0;
char prefix[16]; char prefix[16];
FILE *logfile_fp, *pktlog_fp; FILE *logfile_fp, *pktlog_fp;
struct Xorriso_lsT *msglist;
static int num_channels= 4; static int num_channels= 4;
static char channel_prefixes[4][4]= {".","R","I","M"}; static char channel_prefixes[4][4]= {".","R","I","M"};
@ -610,22 +673,20 @@ bit15= with bit1 to bit3: close depicted log file
} }
if(result_redirected) { if(result_redirected) {
if(channel_no==1 || channel_no==3) { if(channel_no==1 || channel_no==3) {
msglist= xorriso->result_msglists[xorriso->msglist_stackfill - 1]; ret= Xorriso_write_to_msglist(xorriso,
ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); &(xorriso->result_msglists[xorriso->msglist_stackfill - 1]),
text, 0);
if(ret <= 0) if(ret <= 0)
{ret= -1; goto ex;} { ret= -1; goto ex; }
if(xorriso->result_msglists[xorriso->msglist_stackfill - 1] == NULL)
xorriso->result_msglists[xorriso->msglist_stackfill - 1]= msglist;
} }
} }
if(info_redirected) { if(info_redirected) {
if(channel_no==2 || channel_no==3) { if(channel_no==2 || channel_no==3) {
msglist= xorriso->info_msglists[xorriso->msglist_stackfill - 1]; ret= Xorriso_write_to_msglist(xorriso,
ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); &(xorriso->info_msglists[xorriso->msglist_stackfill - 1]),
text, 0);
if(ret <= 0) if(ret <= 0)
{ret= -1; goto ex;} { ret= -1; goto ex; }
if(xorriso->info_msglists[xorriso->msglist_stackfill - 1] == NULL)
xorriso->info_msglists[xorriso->msglist_stackfill - 1]= msglist;
} }
} }
if((channel_no == 1 && result_redirected) || if((channel_no == 1 && result_redirected) ||
@ -718,10 +779,17 @@ ex:
int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle, int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
int flag) int flag)
{ {
int ret, locked= 0;
ret= Xorriso_lock_outlists(xorriso, 0);
if(ret != 0)
{ret= -1; goto ex;}
locked= 1;
if(xorriso->msglist_stackfill + 1 >= Xorriso_max_outlist_stacK) { if(xorriso->msglist_stackfill + 1 >= Xorriso_max_outlist_stacK) {
Xorriso_msgs_submit(xorriso, 0, Xorriso_msgs_submit(xorriso, 0,
"Overflow of message output redirection stack", 0, "FATAL", 0); "Overflow of message output redirection stack", 0, "FATAL", 0);
return(-1); ret= -1; goto ex;
} }
if((flag & 3) == 0) if((flag & 3) == 0)
flag|= 3; flag|= 3;
@ -730,21 +798,74 @@ int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
xorriso->info_msglists[xorriso->msglist_stackfill - 1]= NULL; xorriso->info_msglists[xorriso->msglist_stackfill - 1]= NULL;
xorriso->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3; xorriso->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3;
*stack_handle= xorriso->msglist_stackfill - 1; *stack_handle= xorriso->msglist_stackfill - 1;
ret= 1;
ex:;
if(locked)
Xorriso_unlock_outlists(xorriso, 0);
return(ret);
return(1); return(1);
} }
int Xorriso_fetch_outlists(struct XorrisO *xorriso, int stack_handle,
struct Xorriso_lsT **result_list,
struct Xorriso_lsT **info_list, int flag)
{
int ret, locked= 0;
ret= Xorriso_process_msg_queues(xorriso, 0);
if(ret <= 0)
goto ex;
if((flag & 3) == 0)
flag|= 3;
ret= Xorriso_lock_outlists(xorriso, 0);
if(ret != 0)
{ret= -1; goto ex;}
locked= 1;
if(stack_handle == -1)
stack_handle= xorriso->msglist_stackfill - 1;
if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) {
Xorriso_msgs_submit(xorriso, 0,
"Program error: Wrong message output redirection stack handle",
0, "FATAL", 0);
ret= -1; goto ex;
}
if(flag & 1) {
*result_list= xorriso->result_msglists[stack_handle];
xorriso->result_msglists[stack_handle]= NULL;
}
if(flag & 2) {
*info_list= xorriso->info_msglists[stack_handle];
xorriso->info_msglists[stack_handle]= NULL;
}
ret= 1;
ex:;
if(locked)
Xorriso_unlock_outlists(xorriso, 0);
return(ret);
}
int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle, int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle,
struct Xorriso_lsT **result_list, struct Xorriso_lsT **result_list,
struct Xorriso_lsT **info_list, int flag) struct Xorriso_lsT **info_list, int flag)
{ {
int i; int i, ret, locked= 0;
ret= Xorriso_lock_outlists(xorriso, 0);
if(ret != 0)
{ret= -1; goto ex;}
locked= 1;
if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) { if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) {
Xorriso_msgs_submit(xorriso, 0, Xorriso_msgs_submit(xorriso, 0,
"Program error: Wrong message output redirection stack handle", "Program error: Wrong message output redirection stack handle",
0, "FATAL", 0); 0, "FATAL", 0);
return(-1); ret= -1; goto ex;
} }
*result_list= xorriso->result_msglists[stack_handle]; *result_list= xorriso->result_msglists[stack_handle];
*info_list= xorriso->info_msglists[stack_handle]; *info_list= xorriso->info_msglists[stack_handle];
@ -753,7 +874,11 @@ int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle,
xorriso->info_msglists[i - 1]= xorriso->info_msglists[i]; xorriso->info_msglists[i - 1]= xorriso->info_msglists[i];
} }
xorriso->msglist_stackfill--; xorriso->msglist_stackfill--;
return(1); ret= 1;
ex:;
if(locked)
Xorriso_unlock_outlists(xorriso, 0);
return(ret);
} }
@ -972,26 +1097,12 @@ int Xorriso_msgs_submit(struct XorrisO *xorriso,
xorriso->info_text[li+lt]= '\n'; xorriso->info_text[li+lt]= '\n';
xorriso->info_text[li+lt+1]= 0; xorriso->info_text[li+lt+1]= 0;
#ifdef NIX
/* <<< */
Xorriso_info(xorriso,4|(flag&3));
if(os_errno>0) {
sprintf(xorriso->info_text, "%s%s : %s\n",
pfx_list[(flag>>2)&15], sev_text, strerror(os_errno));
Xorriso_info(xorriso,4|(flag&3));
}
#else
if(os_errno>0) { if(os_errno>0) {
sprintf(xorriso->info_text + strlen(xorriso->info_text) - 1, sprintf(xorriso->info_text + strlen(xorriso->info_text) - 1,
" : %s\n", strerror(os_errno)); " : %s\n", strerror(os_errno));
} }
Xorriso_info(xorriso,4|(flag&3)); Xorriso_info(xorriso,4|(flag&3));
#endif
return(1); return(1);
} }

View File

@ -27,6 +27,13 @@
@since major.minor.micro @since major.minor.micro
If this mark is missing, then the feature was present before release 0.5.8. If this mark is missing, then the feature was present before release 0.5.8.
Please note that struct XorrisO and its API calls are _not_ thread-safe in
general. It is not permissible to run two API calls on the same
XorrisO object concurrently.
The only exception is
Xorriso_fetch_outlists()
in order to learn about the ongoing text output of other API calls.
There is a lower level of API which consists of libisofs.h, libburn.h and There is a lower level of API which consists of libisofs.h, libburn.h and
libisoburn.h. One should not mix those calls with the ones of xorriso.h . libisoburn.h. One should not mix those calls with the ones of xorriso.h .
@ -585,6 +592,37 @@ int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
int flag); int flag);
/** Obtain the currently collected text messages of redirected info and
result channel.
The messages are handed out as two lists. Both lists have to be disposed
via Xorriso_lst_destroy_all() when they are no longer needed.
The message lists are either NULL or represented by their first
Xorriso_lsT item.
This call is safe for being used by a concurrent thread while a
xorriso API call is being executed on the same struct XorrisO.
In such a situation, it should not be used with high frequency in order
not to hamper the ongoing xorriso operation by blocking its message
output facility. Ten times per second should be enough.
@since 1.2.6
@param xorriso The environment handle
@param stack_handle An id number returned by Xorriso_push_outlists()
and not yet revoked by Xorriso_pull_outlists().
Submit -1 to address the most recent valid id.
@param result_list Result and mark messages (usually directed to stdout)
@param info_list Info and mark messages (usually directed to stderr)
@param flag Bitfield for control purposes
bit0= fetch result channel
bit1= fetch info channel
If bit0 and bit1 are 0, both channels get fetched.
@return 1 on success, <=0 if failure
*/
int Xorriso_fetch_outlists(struct XorrisO *xorriso, int stack_handle,
struct Xorriso_lsT **result_list,
struct Xorriso_lsT **info_list, int flag);
/** Disable the redirection given by stack_handle. If it was the current /** Disable the redirection given by stack_handle. If it was the current
receiver of messages then switch output to the next older redirection receiver of messages then switch output to the next older redirection
resp. to the normal channels if no redirections are stacked any more. resp. to the normal channels if no redirections are stacked any more.
@ -594,7 +632,9 @@ int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
The message lists are either NULL or represented by their first The message lists are either NULL or represented by their first
Xorriso_lsT item. Xorriso_lsT item.
@param xorriso The environment handle @param xorriso The environment handle
@param stack_handle The id number returned by Xorriso_push_outlists() @param stack_handle An id number returned by Xorriso_push_outlists()
and not yet revoked by Xorriso_pull_outlists().
This handle is invalid after the call.
@param result_list Result and mark messages (usually directed to stdout) @param result_list Result and mark messages (usually directed to stdout)
@param info_list Info and mark messages (usually directed to stderr) @param info_list Info and mark messages (usually directed to stderr)
@param flag unused yet, submit 0 @param flag unused yet, submit 0

View File

@ -561,6 +561,11 @@ struct XorrisO { /* the global context of xorriso */
*/ */
int msglist_stackfill; int msglist_stackfill;
int lib_msg_queue_lock_ini;
int result_msglists_lock_ini;
pthread_mutex_t lib_msg_queue_lock;
pthread_mutex_t result_msglists_lock;
int status_history_max; /* for -status long_history */ int status_history_max; /* for -status long_history */
/* 0= no logging of SCSI commands, 1= to stderr */ /* 0= no logging of SCSI commands, 1= to stderr */

View File

@ -1 +1 @@
#define Xorriso_timestamP "2012.09.09.181723" #define Xorriso_timestamP "2012.09.11.092703"