diff options
author | Keith Packard <keithp@keithp.com> | 2011-03-24 11:06:57 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-03-24 17:12:00 -0700 |
commit | 7ccbec801e9ee32fc110db730dfec674a94dea21 (patch) | |
tree | ed402cd55eca144eb011ff7253ee1fd5b0f7698d | |
parent | ec133abc4bd8caba15ed54e18621b816afb06981 (diff) |
Recover from i830_dri2_add_frame_event out-of-memory condition
If adding either the frame or client resources fails, we need to clean
up afterwards properly.
First, add_frame_event needs to internally clean up after itself by
undoing any partial execution. Second, the callers need to look at the
return value and free the swap/flip info structure when necessary.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
-rw-r--r-- | src/intel_dri.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/intel_dri.c b/src/intel_dri.c index 3b808230..16e42f16 100644 --- a/src/intel_dri.c +++ b/src/intel_dri.c @@ -625,8 +625,10 @@ i830_dri2_add_frame_event(DRI2FrameEventPtr frame_event) if (!AddResource(frame_event->client_id, frame_event_client_type, frame_event)) return FALSE; - if (!AddResource(frame_event->drawable_id, frame_event_drawable_type, frame_event)) + if (!AddResource(frame_event->drawable_id, frame_event_drawable_type, frame_event)) { + FreeResourceByType(frame_event->client_id, frame_event_client_type, TRUE); return FALSE; + } return TRUE; } @@ -705,7 +707,10 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel, flip_info->event_data = data; flip_info->frame = target_msc; - i830_dri2_add_frame_event(flip_info); + if (!i830_dri2_add_frame_event(flip_info)) { + free(flip_info); + return FALSE; + } /* Page flip the full screen buffer */ back_priv = back->driverPrivate; @@ -955,11 +960,16 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, swap_info->event_data = data; swap_info->front = front; swap_info->back = back; + + if (!i830_dri2_add_frame_event(swap_info)) { + free(swap_info); + swap_info = NULL; + goto blit_fallback; + } + I830DRI2ReferenceBuffer(front); I830DRI2ReferenceBuffer(back); - i830_dri2_add_frame_event(swap_info); - /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; if (pipe > 0) |