From 8a0c1bcb5240b35cbdd1ec2371965fcc46ecf4b1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Jun 2011 23:56:17 +0100 Subject: [PATCH] intel: Catch sigbus and propagate GL_OUT_OF_MEMORY --- src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 8 +++- src/mesa/drivers/dri/intel/intel_tex_image.c | 50 +++++++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index ada22af..4815717 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -332,6 +332,7 @@ intel_miptree_image_map(struct intel_context * intel, GLuint * row_stride, GLuint * image_offsets) { GLuint x, y; + GLubyte *map; if (row_stride) *row_stride = mt->region->pitch * mt->cpp; @@ -358,8 +359,11 @@ intel_miptree_image_map(struct intel_context * intel, DBG("%s: (%d,%d) -> (%d, %d)/%d\n", __FUNCTION__, face, level, x, y, mt->region->pitch * mt->cpp); - return intel_region_map(intel, mt->region) + - (x + y * mt->region->pitch) * mt->cpp; + map = intel_region_map(intel, mt->region); + if (map == NULL) + return NULL; + + return map + (x + y * mt->region->pitch) * mt->cpp; } } diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 9154b83..608ca79 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -300,6 +300,36 @@ try_pbo_zcopy(struct intel_context *intel, return GL_TRUE; } +#include +#include +static struct sigbus_catcher { + pthread_mutex_t mutex; + jmp_buf env; + void (*old)(int); +} _sc = { .mutex = PTHREAD_MUTEX_INITIALIZER }; + +static void intel_miptree_image_map_signal(int sig) +{ + siglongjmp(_sc.env, 1); +} + +static void catch_sigbus_unwind(void) +{ + signal(SIGBUS, _sc.old); + pthread_mutex_unlock(&_sc.mutex); +} + +static int catch_sigbus(void) +{ + pthread_mutex_lock(&_sc.mutex); + if (sigsetjmp(_sc.env, 0)) { + catch_sigbus_unwind(); + return 1; + } + + _sc.old = signal(SIGBUS, intel_miptree_image_map_signal); + return 0; +} static void intelTexImage(struct gl_context * ctx, @@ -445,8 +475,17 @@ intelTexImage(struct gl_context * ctx, intelImage->level, &dstRowStride, intelImage->base.ImageOffsets); - if (texImage->Data == NULL) + if (texImage->Data == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); return; + } + + if (catch_sigbus()) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + return; + } } texImage->RowStride = dstRowStride / intelImage->mt->cpp; @@ -510,6 +549,7 @@ intelTexImage(struct gl_context * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); if (intelImage->mt) { + catch_sigbus_unwind(); if (pixels != NULL) intel_miptree_image_unmap(intel, intelImage->mt); texImage->Data = NULL; @@ -614,6 +654,13 @@ intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level, if (intelImage->base.Data == NULL) return; + if (catch_sigbus()) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + return; + } + intelImage->base.RowStride /= intelImage->mt->cpp; } else { @@ -641,6 +688,7 @@ intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level, /* Unmap */ if (intelImage->mt) { + catch_sigbus_unwind(); intel_miptree_image_unmap(intel, intelImage->mt); intelImage->base.Data = NULL; } -- 1.7.5.1