diff options
author | Yang Rong <rong.r.yang@intel.com> | 2013-08-14 11:08:01 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@linux.intel.com> | 2013-08-14 13:32:18 +0800 |
commit | ffaaa201edaa1bd72519958abdc356af47bde021 (patch) | |
tree | ec760ef7cd8df417942eab1dea7ed9a3bd9a3c49 /src/cl_event.c | |
parent | 98bfaa78f5968168d3b12a2a181e6d2aa026f500 (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.c | 21 |
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) { |