]> granicus.if.org Git - libevent/commit
be_pair: release shared lock with the latest of bufferevent_pair
authorAzat Khuzhin <a3at.mail@gmail.com>
Sat, 3 Jan 2015 16:37:15 +0000 (19:37 +0300)
committerAzat Khuzhin <a3at.mail@gmail.com>
Sun, 25 Jan 2015 21:40:02 +0000 (00:40 +0300)
commit92a359ee3adf4636db508e6c6d7179d4d59eaafc
tree3e1e7abcc34dd68db75bd40a70e43de4a2c28899
parent0b49ae34594533daa82c06a506078de9e336a013
be_pair: release shared lock with the latest of bufferevent_pair

Then next code sample will use free'd lock:
  evthread_use_pthreads();
  ...
  assert(!bufferevent_pair_new(base, BEV_OPT_THREADSAFE, pair));
  ...
  bufferevent_free(pair[0]); # refcnt == 0 -> unlink
  bufferevent_free(pair[1]); # refcnt == 0 -> unlink
  ...
  event_base_free() -> finalizers -> EVTHREAD_FREE_LOCK(bev1->lock)
                                  -> BEV_LOCK(bev2->lock) <-- *already freed*

While if you will reverse the order:
  bufferevent_free(pair[1]); # refcnt == 0 -> unlink
  bufferevent_free(pair[0]); # refcnt == 0 -> unlink
  ...
  event_base_free() -> finalizers -> BEV_LOCK(bev2->lock)/!own_lock/BEV_UNLOCK(bev2->lock)
                                  -> EVTHREAD_FREE_LOCK(bev1->lock) (own_lock)

It is ok now, but I guess that it will be better to relax order of
freeing pairs.
bufferevent_pair.c