From 1a629bb4044c6585e3857d09aa4033b8ce94cc17 Mon Sep 17 00:00:00 2001
From: Timothy Strelchun <Timothy.Strelchun@Intel.Com>
Date: Sat, 19 Jun 2010 17:11:52 -0700
Subject: [PATCH 3/6] Fixed _dfb_windowstack_inputdevice_listener race condition with layer context

Fixed a race condition when _dfb_windowstack_inputdevice_listener 
begins using a layer context, that is then destroyed before the 
listener has finished using it.  This problem occurs because the 
layer context's reference count was never incremented to account 
for the listener's reference to it that it stored and subsequently 
used.  Rather than establishing a reference count cycle (with the 
window stack having a reference to the layer context which has a 
reference to the window stack for which additional complexity 
would be needed to break), the listener now just increments the 
layer context's reference count prior to usage and then decrements 
it.
---
 src/core/windowstack.c |   25 ++++++++++++++++++++++++-
 1 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/src/core/windowstack.c b/src/core/windowstack.c
index c8f30aa..c28ef54 100644
--- a/src/core/windowstack.c
+++ b/src/core/windowstack.c
@@ -718,9 +718,29 @@ _dfb_windowstack_inputdevice_listener( const void *msg_data,
      D_ASSERT( msg_data != NULL );
      D_MAGIC_ASSERT( stack, CoreWindowStack );
 
+     // Dynamically add/decrease the ref to the layer context when using the 
+     // layer context.  This will prevent the layer context from being 
+     // destroyed when it is being used.
+
+     int num = 0;
+
+     // Make sure the layer context's reference count is non-zero.  If it is, 
+     // return early and indicate the listener should be removed.  In this 
+     // scenario, this prevents the object_reference_watcher from being called 
+     // more than once triggered by the reference count changing from 1 to 0 
+     // again.
+     if (dfb_layer_context_ref_stat( stack->context, &num ) || num == 0)
+          return RS_REMOVE;
+
+     // Increase the layer context's reference count.
+     if (dfb_layer_context_ref( stack->context ))
+          return RS_REMOVE;
+
      /* Lock the window stack. */
-     if (dfb_windowstack_lock( stack ))
+     if (dfb_windowstack_lock( stack )) {
+          dfb_layer_context_unref( stack->context );
           return RS_REMOVE;
+     }
 
      /* Call the window manager to dispatch the event. */
      if (dfb_layer_context_active( stack->context ))
@@ -729,6 +749,9 @@ _dfb_windowstack_inputdevice_listener( const void *msg_data,
      /* Unlock the window stack. */
      dfb_windowstack_unlock( stack );
 
+     // Decrease the layer context's reference count.
+     dfb_layer_context_unref( stack->context );
+
      return RS_OK;
 }
 
-- 
1.6.1.9.g97c34

