Fix locking issue in blr_close_binlog
In blr_open_binlog the refcnt increase of file which is already open is protected by router->fileslock. In blr_close_binlog the decrease of the refcnt was protected by file->lock. This lead to a situation where it was possible that a file was closed and the file instance freed, even though it just had been taken into use by somebody else. This is now fixed by solely using the router->fileslock for protecting the increase and decrease of the refcnt.
This commit is contained in:
@ -643,11 +643,10 @@ struct stat statb;
|
|||||||
void
|
void
|
||||||
blr_close_binlog(ROUTER_INSTANCE *router, BLFILE *file)
|
blr_close_binlog(ROUTER_INSTANCE *router, BLFILE *file)
|
||||||
{
|
{
|
||||||
spinlock_acquire(&file->lock);
|
spinlock_acquire(&router->fileslock);
|
||||||
file->refcnt--;
|
file->refcnt--;
|
||||||
if (file->refcnt == 0)
|
if (file->refcnt == 0)
|
||||||
{
|
{
|
||||||
spinlock_acquire(&router->fileslock);
|
|
||||||
if (router->files == file)
|
if (router->files == file)
|
||||||
router->files = file->next;
|
router->files = file->next;
|
||||||
else
|
else
|
||||||
@ -658,18 +657,18 @@ blr_close_binlog(ROUTER_INSTANCE *router, BLFILE *file)
|
|||||||
if (ptr)
|
if (ptr)
|
||||||
ptr->next = file->next;
|
ptr->next = file->next;
|
||||||
}
|
}
|
||||||
spinlock_release(&router->fileslock);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
|
spinlock_release(&router->fileslock);
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
close(file->fd);
|
close(file->fd);
|
||||||
file->fd = -1;
|
file->fd = -1;
|
||||||
}
|
|
||||||
|
|
||||||
if (file->refcnt == 0) {
|
|
||||||
spinlock_release(&file->lock);
|
|
||||||
|
|
||||||
free(file);
|
free(file);
|
||||||
} else {
|
|
||||||
spinlock_release(&file->lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user