New API call Xorriso_peek_outlists()

This commit is contained in:
2012-09-15 17:04:32 +00:00
parent fc689bc70b
commit 1a684c064b
7 changed files with 175 additions and 26 deletions

View File

@ -522,44 +522,76 @@ ex:;
}
static int Xorriso_lock_outlists(struct XorrisO *xorriso, int flag)
/* @param flag bit0= no error message in case of failure
*/
static int Xorriso_obtain_lock(struct XorrisO *xorriso,
pthread_mutex_t *lock_handle,
char *purpose, int flag)
{
int ret;
static int complaints= 0, complaint_limit= 5;
ret= pthread_mutex_lock(&(xorriso->result_msglists_lock));
ret= pthread_mutex_lock(lock_handle);
if(ret != 0) {
if(flag & 1)
return(-1);
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
if(complaints <= complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_lock() for outlists returns %d\n",
ret);
"xorriso : pthread_mutex_lock() for %s returns %d\n",
purpose, ret);
return(-1);
}
return(1);
}
static int Xorriso_unlock_outlists(struct XorrisO *xorriso, int flag)
/* @param flag bit0= no error message in case of failure
*/
static int Xorriso_release_lock(struct XorrisO *xorriso,
pthread_mutex_t *lock_handle,
char *purpose, int flag)
{
int ret;
static int complaints= 0, complaint_limit= 5;
ret= pthread_mutex_unlock(&(xorriso->result_msglists_lock));
ret= pthread_mutex_unlock(lock_handle);
if(ret != 0) {
if(flag & 1)
return(0);
/* Cannot report failure through the failing message output system */
complaints++;
if(complaints < complaint_limit)
if(complaints <= complaint_limit)
fprintf(stderr,
"xorriso : pthread_mutex_unlock() for outlists returns %d\n",
ret);
"xorriso : pthread_mutex_unlock() for %s returns %d\n",
purpose, ret);
return(0);
}
return(1);
}
static int Xorriso_lock_outlists(struct XorrisO *xorriso, int flag)
{
int ret;
ret= Xorriso_obtain_lock(xorriso, &(xorriso->result_msglists_lock),
"outlists", 0);
return(ret);
}
static int Xorriso_unlock_outlists(struct XorrisO *xorriso, int flag)
{
int ret;
ret= Xorriso_release_lock(xorriso, &(xorriso->result_msglists_lock),
"outlists", 0);
return(ret);
}
static int Xorriso_write_to_msglist(struct XorrisO *xorriso,
struct Xorriso_lsT **xorriso_msglist,
char *text, int flag)
@ -850,13 +882,6 @@ int Xorriso_fetch_outlists(struct XorrisO *xorriso, int stack_handle,
#ifdef Xorriso_fetch_with_msg_queueS
/* >>> This would need more locking around
xorriso->problem_status= sev;
Probably also locking of
Xorriso_info(), Xorriso_result
because unredirected output could collide.
*/
ret= Xorriso_process_msg_queues(xorriso, 0);
if(ret <= 0)
goto ex;
@ -896,6 +921,59 @@ ex:;
}
int Xorriso_peek_outlists(struct XorrisO *xorriso, int stack_handle,
int timeout, int flag)
{
int ret, locked= 0, yes= 0;
static int u_wait= 19000;
time_t start_time;
if((flag & 3) == 0)
flag|= 3;
if(stack_handle == -1)
stack_handle= xorriso->msglist_stackfill - 1;
start_time= time(NULL);
try_again:;
ret= Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 0);
if(ret <= 0)
{yes= -2; goto ex;}
locked= 1;
yes= 0;
if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill)
{yes= -1; goto ex;}
if(flag & 1)
yes|= (xorriso->result_msglists[stack_handle] != NULL);
if(flag & 2)
yes|= (xorriso->info_msglists[stack_handle] != NULL);
if(xorriso->msg_watcher_state == 2 && xorriso->msgw_msg_pending)
yes|= 2;
ret= Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 0);
if(ret <= 0)
{yes= -2; goto ex;}
locked= 0;
if(yes && (flag & 4)) {
usleep(u_wait);
if(time(NULL) <= start_time + timeout)
goto try_again;
}
ex:;
if(locked) {
ret= Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 0);
if(ret <= 0 && yes >= 0)
yes= -2;
}
return(yes);
}
int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle,
struct Xorriso_lsT **result_list,
struct Xorriso_lsT **info_list, int flag)
@ -1025,18 +1103,31 @@ static void *Xorriso_msg_watcher(void *state_pt)
if(xorriso->msg_watcher_state == 3)
break;
Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
xorriso->msgw_msg_pending= 1;
ret= Xorriso_fetch_outlists(xorriso, -1, &result_list, &info_list, 3);
if(ret < 0)
break;
if(ret > 0) {
/* Process fetched lines */
xorriso->msgw_msg_pending= 2;
Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
ret= Xorriso_process_msg_lists(xorriso, result_list, info_list,
&line_count, 0);
xorriso->msgw_msg_pending= 0;
Xorriso_lst_destroy_all(&result_list, 0);
Xorriso_lst_destroy_all(&info_list, 0);
if(ret < 0)
break;
} else {
xorriso->msgw_msg_pending= 0;
Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
}
xorriso->msgw_msg_pending= 0;
if(ret < 0)
break;
if(line_count < sleep_thresh)
usleep(u_wait);
@ -1179,13 +1270,24 @@ int Xorriso_stop_msg_watcher(struct XorrisO *xorriso, int flag)
usleep(u_wait);
}
Xorriso_obtain_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
xorriso->msgw_msg_pending= 1;
ret= Xorriso_pull_outlists(xorriso, xorriso->msgw_stack_handle,
&result_list, &info_list, 0);
if(ret > 0) {
xorriso->msgw_msg_pending= 2;
Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
Xorriso_process_msg_lists(xorriso, result_list, info_list,
&line_count, 0);
xorriso->msgw_msg_pending= 0;
Xorriso_lst_destroy_all(&result_list, 0);
Xorriso_lst_destroy_all(&info_list, 0);
} else {
xorriso->msgw_msg_pending= 0;
Xorriso_release_lock(xorriso, &(xorriso->msgw_fetch_lock),
"message watcher fetch operation", 1);
}
xorriso->msgw_result_handler= NULL;