Browse Source

Added async_block_progress() and default SIGUPDATE handler.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
1a79437888
2 changed files with 79 additions and 3 deletions
  1. 58
    3
      src/core/async.c
  2. 21
    0
      src/include/gpxe/async.h

+ 58
- 3
src/core/async.c View File

153
 	assert ( waited_aid >= 0 );
153
 	assert ( waited_aid >= 0 );
154
 }
154
 }
155
 
155
 
156
+/**
157
+ * SIGUPDATE 'ignore' handler
158
+ *
159
+ * @v async		Asynchronous operation
160
+ * @v signal		Signal received
161
+ */
162
+static void async_ignore_sigupdate ( struct async *async,
163
+				     enum signal signal ) {
164
+	struct async *child;
165
+
166
+	assert ( async != NULL );
167
+	assert ( signal == SIGUPDATE );
168
+
169
+	async_signal_children ( async, signal );
170
+	async->completed = 0;
171
+	async->total = 0;
172
+	list_for_each_entry ( child, &async->children, siblings ) {
173
+		async->completed += child->completed;
174
+		async->total += child->total;
175
+	}
176
+}
177
+
156
 /**
178
 /**
157
  * 'Ignore' signal handler
179
  * 'Ignore' signal handler
158
  *
180
  *
170
 	case SIGCHLD:
192
 	case SIGCHLD:
171
 		async_ignore_sigchld ( async, signal );
193
 		async_ignore_sigchld ( async, signal );
172
 		break;
194
 		break;
173
-	case SIGKILL:
174
 	case SIGUPDATE:
195
 	case SIGUPDATE:
196
+		async_ignore_sigupdate ( async, signal );
197
+		break;
198
+	case SIGKILL:
175
 	default:
199
 	default:
176
 		/* Nothing to do */
200
 		/* Nothing to do */
177
 		break;
201
 		break;
391
 	}
415
 	}
392
 }
416
 }
393
 
417
 
418
+/**
419
+ * Wait for any child asynchronous operation to complete, with progress bar
420
+ * 
421
+ * @v child		Child asynchronous operation
422
+ * @v rc		Child exit status to fill in, or NULL
423
+ * @ret aid		Asynchronous operation ID, or -1 on error
424
+ */
425
+aid_t async_wait_progress ( struct async *async, int *rc ) {
426
+	struct async *child;
427
+	long last_progress = -1;
428
+	long progress;
429
+	aid_t child_aid;
430
+
431
+	do {
432
+		step();
433
+		async_signal ( async, SIGUPDATE );
434
+		if ( async->total ) {
435
+			progress = ( async->completed / (async->total / 100) );
436
+			if ( progress != last_progress )
437
+				printf ( "\rProgress: %d%%", progress );
438
+			last_progress = progress;
439
+		}
440
+		child_aid = async_wait ( async, rc, 0 );
441
+	} while ( *rc == -EINPROGRESS );
442
+
443
+	printf ( "\n" );
444
+	return child_aid;
445
+}
446
+
394
 /**
447
 /**
395
  * Default asynchronous operations
448
  * Default asynchronous operations
396
  *
449
  *
400
  */
453
  */
401
 struct async_operations default_async_operations = {
454
 struct async_operations default_async_operations = {
402
 	.signal = {
455
 	.signal = {
403
-		[SIGCHLD] = SIG_IGN,
456
+		[SIGCHLD]	= SIG_IGN,
457
+		[SIGUPDATE]	= SIG_IGN,
404
 	},
458
 	},
405
 };
459
 };
406
 
460
 
414
  */
468
  */
415
 struct async_operations orphan_async_operations = {
469
 struct async_operations orphan_async_operations = {
416
 	.signal = {
470
 	.signal = {
417
-		[SIGCHLD] = SIG_DFL,
471
+		[SIGCHLD]	= SIG_DFL,
472
+		[SIGUPDATE]	= SIG_IGN,
418
 	},
473
 	},
419
 };
474
 };

+ 21
- 0
src/include/gpxe/async.h View File

204
 		rc;						\
204
 		rc;						\
205
 	} )
205
 	} )
206
 
206
 
207
+/**
208
+ * Execute and block on an asynchronous operation, with progress indicator
209
+ *
210
+ * @v async_temp	Temporary asynchronous operation structure to use
211
+ * @v START		Code used to start the asynchronous operation
212
+ * @ret rc		Return status code
213
+ *
214
+ * As for async_block(), the argument START is a code snippet; it
215
+ * should initiate an asynchronous operation as a child of @c
216
+ * async_temp and return an error status code if it failed to do so
217
+ * (e.g. due to malloc() failure).
218
+ */
219
+#define async_block_progress( async_temp, START ) ( {		\
220
+		int rc;						\
221
+								\
222
+	 	async_init_orphan ( async_temp );		\
223
+		if ( ( rc = START ) == 0 )			\
224
+			async_wait_progress ( async_temp, &rc );\
225
+		rc;						\
226
+	} )
227
+
207
 #endif /* _GPXE_ASYNC_H */
228
 #endif /* _GPXE_ASYNC_H */

Loading…
Cancel
Save