[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] deadlock in callbacks



On Thu, Feb 19, 2015 at 06:36:52AM -0800, Marco Graziano wrote:
> On Thu, Feb 19, 2015 at 6:29 AM, Azat Khuzhin <a3at.mail@xxxxxxxxx> wrote:
> > > > Do you lock this device->pending->bufev somehow (or in some inner
> > frame)?
> > > > If so then *deadlock is possible*, iff in thread#1
> > evbuffer_get_length()
> > > > called with this bufev output, and this is the only issue that can
> > > > happens here, if I understand you snippets+backtraces correctly.
> >
> > You read the paragraph above, do you?
> >
> 
> Yes I did. I imagine you refer to additional locks. I removed all my locks
> from everywhere.

Sorry if I'm not clearly expressed here.
The deadlock is possible even without your internal locks.

Look at the following calling chains:
thread#5:                                           thread#1:
  - lock(bufev->lock) # waiting, blocked by #t1
- bufferevent_setcb(bufev=0x64f350, ...)
- send_http_response()                                - lock() # waiting, blocked by #t5
- device_chunk_cb()                                 - evbuffer_get_length("device1->pending->bufev")
- device_read_cb(bev=0x6396d0, arg="device1")       - device_write_cb(bev=0x64f350, arg="device1")
- bufferevent_trigger_nolock_()                     - bufferevent_trigger_nolock_()
  - lock(bufev->lock (0x6396d0))                      - lock(bufev->lock(0x64f350))
- bufferevent_readcb(arg=0x6396d0)                  - bufferevent_writecb(arg=0x64f350)
- event_persist_closure()                           - event_persist_closure()

In "" vars according to you code (and if names are equal -- values equal too).
And in case my guessing about evbuffer_get_length() parameters is correct, and
your lock device1->pending->bufev somehow in thread#5 (i.e. in
device_chunk_cb()/send_http_response()) -- it is deadlock.

BTW txt version of the line-by-line backtrace is available here (since
you email client could break spaces between them):
https://gist.github.com/azat/f9ad5cb197fdf5cedfb0

Something like this could tell you valgrind --tool=drd/helgrind, as I already
suggested. (I'm still strongly recommending you to run your program under
valgrind).

And according to this analysis (*if it is correct of course*), you could
understand why unlock/defered helps.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.