summaryrefslogtreecommitdiff
path: root/src/cl_event.c
diff options
context:
space:
mode:
authorYang Rong <rong.r.yang@intel.com>2013-08-14 11:08:01 +0800
committerZhigang Gong <zhigang.gong@linux.intel.com>2013-08-14 13:32:18 +0800
commitffaaa201edaa1bd72519958abdc356af47bde021 (patch)
treeec760ef7cd8df417942eab1dea7ed9a3bd9a3c49 /src/cl_event.c
parent98bfaa78f5968168d3b12a2a181e6d2aa026f500 (diff)
Fix event pthread_mutex_lock dead lock.
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>
Diffstat (limited to 'src/cl_event.c')
-rw-r--r--src/cl_event.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/cl_event.c b/src/cl_event.c
index 48f24e5e..e882c7c5 100644
--- a/src/cl_event.c
+++ b/src/cl_event.c
@@ -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) {