mirror of
https://github.com/xcat2/xNBA.git
synced 2025-01-18 21:43:14 +00:00
Added async_block_progress() and default SIGUPDATE handler.
This commit is contained in:
parent
c42a384709
commit
1a79437888
@ -153,6 +153,28 @@ static void async_ignore_sigchld ( struct async *async, enum signal signal ) {
|
||||
assert ( waited_aid >= 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* SIGUPDATE 'ignore' handler
|
||||
*
|
||||
* @v async Asynchronous operation
|
||||
* @v signal Signal received
|
||||
*/
|
||||
static void async_ignore_sigupdate ( struct async *async,
|
||||
enum signal signal ) {
|
||||
struct async *child;
|
||||
|
||||
assert ( async != NULL );
|
||||
assert ( signal == SIGUPDATE );
|
||||
|
||||
async_signal_children ( async, signal );
|
||||
async->completed = 0;
|
||||
async->total = 0;
|
||||
list_for_each_entry ( child, &async->children, siblings ) {
|
||||
async->completed += child->completed;
|
||||
async->total += child->total;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Ignore' signal handler
|
||||
*
|
||||
@ -170,8 +192,10 @@ void async_ignore_signal ( struct async *async, enum signal signal ) {
|
||||
case SIGCHLD:
|
||||
async_ignore_sigchld ( async, signal );
|
||||
break;
|
||||
case SIGKILL:
|
||||
case SIGUPDATE:
|
||||
async_ignore_sigupdate ( async, signal );
|
||||
break;
|
||||
case SIGKILL:
|
||||
default:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
@ -391,6 +415,35 @@ aid_t async_wait ( struct async *async, int *rc, int block ) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for any child asynchronous operation to complete, with progress bar
|
||||
*
|
||||
* @v child Child asynchronous operation
|
||||
* @v rc Child exit status to fill in, or NULL
|
||||
* @ret aid Asynchronous operation ID, or -1 on error
|
||||
*/
|
||||
aid_t async_wait_progress ( struct async *async, int *rc ) {
|
||||
struct async *child;
|
||||
long last_progress = -1;
|
||||
long progress;
|
||||
aid_t child_aid;
|
||||
|
||||
do {
|
||||
step();
|
||||
async_signal ( async, SIGUPDATE );
|
||||
if ( async->total ) {
|
||||
progress = ( async->completed / (async->total / 100) );
|
||||
if ( progress != last_progress )
|
||||
printf ( "\rProgress: %d%%", progress );
|
||||
last_progress = progress;
|
||||
}
|
||||
child_aid = async_wait ( async, rc, 0 );
|
||||
} while ( *rc == -EINPROGRESS );
|
||||
|
||||
printf ( "\n" );
|
||||
return child_aid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default asynchronous operations
|
||||
*
|
||||
@ -400,7 +453,8 @@ aid_t async_wait ( struct async *async, int *rc, int block ) {
|
||||
*/
|
||||
struct async_operations default_async_operations = {
|
||||
.signal = {
|
||||
[SIGCHLD] = SIG_IGN,
|
||||
[SIGCHLD] = SIG_IGN,
|
||||
[SIGUPDATE] = SIG_IGN,
|
||||
},
|
||||
};
|
||||
|
||||
@ -414,6 +468,7 @@ struct async_operations default_async_operations = {
|
||||
*/
|
||||
struct async_operations orphan_async_operations = {
|
||||
.signal = {
|
||||
[SIGCHLD] = SIG_DFL,
|
||||
[SIGCHLD] = SIG_DFL,
|
||||
[SIGUPDATE] = SIG_IGN,
|
||||
},
|
||||
};
|
||||
|
@ -204,4 +204,25 @@ static inline aid_t async_init_orphan ( struct async *async ) {
|
||||
rc; \
|
||||
} )
|
||||
|
||||
/**
|
||||
* Execute and block on an asynchronous operation, with progress indicator
|
||||
*
|
||||
* @v async_temp Temporary asynchronous operation structure to use
|
||||
* @v START Code used to start the asynchronous operation
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* As for async_block(), the argument START is a code snippet; it
|
||||
* should initiate an asynchronous operation as a child of @c
|
||||
* async_temp and return an error status code if it failed to do so
|
||||
* (e.g. due to malloc() failure).
|
||||
*/
|
||||
#define async_block_progress( async_temp, START ) ( { \
|
||||
int rc; \
|
||||
\
|
||||
async_init_orphan ( async_temp ); \
|
||||
if ( ( rc = START ) == 0 ) \
|
||||
async_wait_progress ( async_temp, &rc );\
|
||||
rc; \
|
||||
} )
|
||||
|
||||
#endif /* _GPXE_ASYNC_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user