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_eval_problem_status;
Xorriso_execute_option;
Xorriso_fetch_outlists;
Xorriso_get_problem_status;
Xorriso_interpreter;
Xorriso_lst_destroy_all;

View File

@ -25,6 +25,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#ifdef HAVE_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->msglist_flags[i]= 0;
}
m->lib_msg_queue_lock_ini= 0;
m->result_msglists_lock_ini= 0;
m->msglist_stackfill= 0;
m->status_history_max= Xorriso_status_history_maX;
m->scsi_log= 0;
@ -433,6 +436,14 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
if(ret <= 0)
goto failure;
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)
free(leafname);
@ -513,6 +524,10 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag)
for(i= 0; i < Xorriso_max_appended_partitionS; i++)
if(m->appended_partitions[i] != NULL)
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);

View File

@ -23,6 +23,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
@ -469,15 +470,26 @@ cannot:;
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
{
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];
#ifdef Xorriso_with_libjtE
char *msg;
#endif
if(!xorriso->libs_are_started)
return(1);
if(!xorriso->libs_are_started) {
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++) {
while(1) {
tunneled= 0;
@ -536,6 +548,17 @@ int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
count);
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);
}

View File

@ -23,6 +23,8 @@
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
/* for -charset */
#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,
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;
char prefix[16];
FILE *logfile_fp, *pktlog_fp;
struct Xorriso_lsT *msglist;
static int num_channels= 4;
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(channel_no==1 || channel_no==3) {
msglist= xorriso->result_msglists[xorriso->msglist_stackfill - 1];
ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0);
ret= Xorriso_write_to_msglist(xorriso,
&(xorriso->result_msglists[xorriso->msglist_stackfill - 1]),
text, 0);
if(ret <= 0)
{ 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(channel_no==2 || channel_no==3) {
msglist= xorriso->info_msglists[xorriso->msglist_stackfill - 1];
ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0);
ret= Xorriso_write_to_msglist(xorriso,
&(xorriso->info_msglists[xorriso->msglist_stackfill - 1]),
text, 0);
if(ret <= 0)
{ 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) ||
@ -718,10 +779,17 @@ ex:
int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle,
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) {
Xorriso_msgs_submit(xorriso, 0,
"Overflow of message output redirection stack", 0, "FATAL", 0);
return(-1);
ret= -1; goto ex;
}
if((flag & 3) == 0)
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->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3;
*stack_handle= xorriso->msglist_stackfill - 1;
ret= 1;
ex:;
if(locked)
Xorriso_unlock_outlists(xorriso, 0);
return(ret);
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,
struct Xorriso_lsT **result_list,
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) {
Xorriso_msgs_submit(xorriso, 0,
"Program error: Wrong message output redirection stack handle",
0, "FATAL", 0);
return(-1);
ret= -1; goto ex;
}
*result_list= xorriso->result_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->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+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) {
sprintf(xorriso->info_text + strlen(xorriso->info_text) - 1,
" : %s\n", strerror(os_errno));
}
Xorriso_info(xorriso,4|(flag&3));
#endif
return(1);
}

View File

@ -27,6 +27,13 @@
@since major.minor.micro
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
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);
/** 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
receiver of messages then switch output to the next older redirection
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
Xorriso_lsT item.
@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 info_list Info and mark messages (usually directed to stderr)
@param flag unused yet, submit 0

View File

@ -561,6 +561,11 @@ struct XorrisO { /* the global context of xorriso */
*/
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 */
/* 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"