2
0
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:
Michael Brown 2007-01-29 04:15:24 +00:00
parent c42a384709
commit 1a79437888
2 changed files with 79 additions and 3 deletions

View File

@ -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,
},
};

View File

@ -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 */