Fix event pthread_mutex_lock dead lock.
authorYang Rong <rong.r.yang@intel.com>
Wed, 14 Aug 2013 03:08:01 +0000 (11:08 +0800)
committerZhigang Gong <zhigang.gong@linux.intel.com>
Wed, 14 Aug 2013 05:32:18 +0000 (13:32 +0800)
In function cl_event_set_status, between pthread_mutex_lock and pthread_mutex_unlock
will call cl_event_delete, which also require the same lock, cause deak lock.
Unlock it before call cl_event_delete.

Signed-off-by: Yang Rong <rong.r.yang@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
src/cl_event.c

index 48f24e5..e882c7c 100644 (file)
@@ -305,23 +305,36 @@ void cl_event_set_status(cl_event event, cl_int status)
 
   pthread_mutex_lock(&event->ctx->event_lock);
   if(status >= event->status) {
-   return;
+    pthread_mutex_unlock(&event->ctx->event_lock);
+    return;
+  }
+  if(event->status <= CL_COMPLETE) {
+    event->status = status;    //have done enqueue before or doing in another thread
+    pthread_mutex_unlock(&event->ctx->event_lock);
+    return;
   }
 
   if(status <= CL_COMPLETE) {
     if(event->enqueue_cb) {
+      cl_enqueue_handle(&event->enqueue_cb->data);
+      event->status = status;  //Change the event status after enqueue and befor unlock
+
+      pthread_mutex_unlock(&event->ctx->event_lock);
       for(i=0; i<event->enqueue_cb->num_events; i++)
         cl_event_delete(event->enqueue_cb->wait_list[i]);
+      pthread_mutex_lock(&event->ctx->event_lock);
 
-      cl_enqueue_handle(&event->enqueue_cb->data);
       cl_free(event->enqueue_cb);
       event->enqueue_cb = NULL;
     }
-    cl_event_delete(event);
   }
-  event->status = status;
+  if(event->status >= status)  //maybe changed in other threads
+    event->status = status;
   pthread_mutex_unlock(&event->ctx->event_lock);
 
+  if(event->status <= CL_COMPLETE)
+    cl_event_delete(event);
+
   /* Call user callback */
   user_cb = event->user_cb;
   while(user_cb) {