diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-02-22 08:35:50 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-02-22 09:39:35 +0000 |
commit | 59d471de7fc7581b112f37a68714d0e1f8728dfd (patch) | |
tree | 7d021a04bd71edd6f35a9c94a7dedc51f5411845 | |
parent | 1de1104064b5898cbed37e836901694a381c1266 (diff) |
sna: Handle asynchronous signals from threads
By killing the threads and leaking their allocations - marginally
preferrable to losing the entire Xserver.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_threads.c | 16 | ||||
-rw-r--r-- | src/sna/sna_trapezoids_boxes.c | 26 | ||||
-rw-r--r-- | src/sna/sna_trapezoids_imprecise.c | 48 | ||||
-rw-r--r-- | src/sna/sna_trapezoids_precise.c | 48 |
5 files changed, 88 insertions, 51 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 1b0a4e58..0b5de8e5 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -1017,6 +1017,7 @@ void sna_threads_init(void); int sna_use_threads (int width, int height, int threshold); void sna_threads_run(void (*func)(void *arg), void *arg); void sna_threads_wait(void); +void sna_threads_kill(void); void sna_image_composite(pixman_op_t op, pixman_image_t *src, diff --git a/src/sna/sna_threads.c b/src/sna/sna_threads.c index 6627cbda..8f554965 100644 --- a/src/sna/sna_threads.c +++ b/src/sna/sna_threads.c @@ -205,6 +205,22 @@ void sna_threads_wait(void) } } +void sna_threads_kill(void) +{ + int n; + + ERR(("kill %d threads\n", max_threads)); + assert(max_threads > 0); + + for (n = 0; n < max_threads; n++) + pthread_cancel(threads[n].thread); + + for (n = 0; n < max_threads; n++) + pthread_join(threads[n].thread, NULL); + + max_threads = 0; +} + int sna_use_threads(int width, int height, int threshold) { int num_threads; diff --git a/src/sna/sna_trapezoids_boxes.c b/src/sna/sna_trapezoids_boxes.c index 6d81da68..d6f0c371 100644 --- a/src/sna/sna_trapezoids_boxes.c +++ b/src/sna/sna_trapezoids_boxes.c @@ -1181,19 +1181,23 @@ composite_unaligned_boxes_inplace(struct sna *sna, dy = (clip.extents.y2 - clip.extents.y1 + num_threads - 1) / num_threads; num_threads = (clip.extents.y2 - clip.extents.y1 + dy - 1) / dy; - for (i = 1; i < num_threads; i++) { - thread[i] = thread[0]; - thread[i].y1 = y; - thread[i].y2 = y += dy; - sna_threads_run(rectilinear_inplace_thread, &thread[i]); - } + if (sigtrap_get() == 0) { + for (i = 1; i < num_threads; i++) { + thread[i] = thread[0]; + thread[i].y1 = y; + thread[i].y2 = y += dy; + sna_threads_run(rectilinear_inplace_thread, &thread[i]); + } - assert(y < clip.extents.y2); - thread[0].y1 = y; - thread[0].y2 = clip.extents.y2; - rectilinear_inplace_thread(&thread[0]); + assert(y < clip.extents.y2); + thread[0].y1 = y; + thread[0].y2 = clip.extents.y2; + rectilinear_inplace_thread(&thread[0]); - sna_threads_wait(); + sna_threads_wait(); + sigtrap_put(); + } else + sna_threads_kill(); pixman_image_unref(thread[0].dst); pixman_image_unref(thread[0].src); diff --git a/src/sna/sna_trapezoids_imprecise.c b/src/sna/sna_trapezoids_imprecise.c index ddf52c2c..93823bb0 100644 --- a/src/sna/sna_trapezoids_imprecise.c +++ b/src/sna/sna_trapezoids_imprecise.c @@ -2851,19 +2851,23 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; - for (n = 1; n < num_threads; n++) { - threads[n] = threads[0]; - threads[n].extents.y1 = y; - threads[n].extents.y2 = y += h; + if (sigtrap_get() == 0) { + for (n = 1; n < num_threads; n++) { + threads[n] = threads[0]; + threads[n].extents.y1 = y; + threads[n].extents.y2 = y += h; - sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]); - } + sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]); + } - assert(y < threads[0].extents.y2); - threads[0].extents.y1 = y; - inplace_x8r8g8b8_thread(&threads[0]); + assert(y < threads[0].extents.y2); + threads[0].extents.y1 = y; + inplace_x8r8g8b8_thread(&threads[0]); - sna_threads_wait(); + sna_threads_wait(); + sigtrap_put(); + } else + sna_threads_kill(); /* leaks thread allocations */ } return true; @@ -3125,19 +3129,23 @@ imprecise_trapezoid_span_inplace(struct sna *sna, h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; - for (n = 1; n < num_threads; n++) { - threads[n] = threads[0]; - threads[n].extents.y1 = y; - threads[n].extents.y2 = y += h; + if (sigtrap_get() == 0) { + for (n = 1; n < num_threads; n++) { + threads[n] = threads[0]; + threads[n].extents.y1 = y; + threads[n].extents.y2 = y += h; - sna_threads_run(inplace_thread, &threads[n]); - } + sna_threads_run(inplace_thread, &threads[n]); + } - assert(y < threads[0].extents.y2); - threads[0].extents.y1 = y; - inplace_thread(&threads[0]); + assert(y < threads[0].extents.y2); + threads[0].extents.y1 = y; + inplace_thread(&threads[0]); - sna_threads_wait(); + sna_threads_wait(); + sigtrap_put(); + } else + sna_threads_kill(); /* leaks thread allocations */ } return true; diff --git a/src/sna/sna_trapezoids_precise.c b/src/sna/sna_trapezoids_precise.c index e5bab16b..bc0a7e7c 100644 --- a/src/sna/sna_trapezoids_precise.c +++ b/src/sna/sna_trapezoids_precise.c @@ -2849,19 +2849,23 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; - for (n = 1; n < num_threads; n++) { - threads[n] = threads[0]; - threads[n].extents.y1 = y; - threads[n].extents.y2 = y += h; + if (sigtrap_get() == 0) { + for (n = 1; n < num_threads; n++) { + threads[n] = threads[0]; + threads[n].extents.y1 = y; + threads[n].extents.y2 = y += h; - sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]); - } + sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]); + } - assert(y < threads[0].extents.y2); - threads[0].extents.y1 = y; - inplace_x8r8g8b8_thread(&threads[0]); + assert(y < threads[0].extents.y2); + threads[0].extents.y1 = y; + inplace_x8r8g8b8_thread(&threads[0]); - sna_threads_wait(); + sna_threads_wait(); + sigtrap_put(); + } else + sna_threads_kill(); /* leaks thread allocations */ } return true; @@ -3124,19 +3128,23 @@ precise_trapezoid_span_inplace(struct sna *sna, h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; - for (n = 1; n < num_threads; n++) { - threads[n] = threads[0]; - threads[n].extents.y1 = y; - threads[n].extents.y2 = y += h; + if (sigtrap_get() == 0) { + for (n = 1; n < num_threads; n++) { + threads[n] = threads[0]; + threads[n].extents.y1 = y; + threads[n].extents.y2 = y += h; - sna_threads_run(inplace_thread, &threads[n]); - } + sna_threads_run(inplace_thread, &threads[n]); + } - assert(y < threads[0].extents.y2); - threads[0].extents.y1 = y; - inplace_thread(&threads[0]); + assert(y < threads[0].extents.y2); + threads[0].extents.y1 = y; + inplace_thread(&threads[0]); - sna_threads_wait(); + sna_threads_wait(); + sigtrap_put(); + } else + sna_threads_kill(); /* leaks thread allocations */ } return true; |