lib/nfs/Connection: fix memory leak (and assertion failure)
nfs_destroy_context() will invoke all pending callbacks with err==-EINTR. In CancellableCallback::Callback(), this will invoke NfsConnection::DeferClose(), which however is only designed to be called from nfs_service(). In non-debug mode, this will leak memory because nfs_close_async() is never called. Workaround: before nfs_destroy_context(), invoke nfs_close_async() on all pending file handles.
This commit is contained in:
@@ -132,6 +132,17 @@ NfsConnection::CancellableCallback::CancelAndScheduleClose(struct nfsfh *fh)
|
||||
Cancel();
|
||||
}
|
||||
|
||||
inline void
|
||||
NfsConnection::CancellableCallback::PrepareDestroyContext()
|
||||
{
|
||||
assert(IsCancelled());
|
||||
|
||||
if (close_fh != nullptr) {
|
||||
connection.InternalClose(close_fh);
|
||||
close_fh = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
NfsConnection::CancellableCallback::Callback(int err, void *data)
|
||||
{
|
||||
@@ -370,6 +381,10 @@ NfsConnection::DestroyContext()
|
||||
if (SocketMonitor::IsDefined())
|
||||
SocketMonitor::Cancel();
|
||||
|
||||
callbacks.ForEach([](CancellableCallback &c){
|
||||
c.PrepareDestroyContext();
|
||||
});
|
||||
|
||||
nfs_destroy_context(context);
|
||||
context = nullptr;
|
||||
}
|
||||
|
Reference in New Issue
Block a user