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>
This commit is contained in:
parent
1de1104064
commit
59d471de7f
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue