lib/nfs/Connection: fix memory leak when cancelling Open()
Close the newly allocated file handle passed to the callback.
This commit is contained in:
parent
10cc87e422
commit
edd003b62a
|
@ -94,6 +94,14 @@ NfsConnection::CancellableCallback::Callback(int err, void *data)
|
||||||
cb.OnNfsError(Error(nfs_domain, err,
|
cb.OnNfsError(Error(nfs_domain, err,
|
||||||
(const char *)data));
|
(const char *)data));
|
||||||
} else {
|
} else {
|
||||||
|
if (open) {
|
||||||
|
/* a nfs_open_async() call was cancelled - to
|
||||||
|
avoid a memory leak, close the newly
|
||||||
|
allocated file handle immediately */
|
||||||
|
struct nfsfh *fh = (struct nfsfh *)data;
|
||||||
|
connection.Close(fh);
|
||||||
|
}
|
||||||
|
|
||||||
connection.callbacks.Remove(*this);
|
connection.callbacks.Remove(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +165,7 @@ NfsConnection::Open(const char *path, int flags, NfsCallback &callback,
|
||||||
{
|
{
|
||||||
assert(!callbacks.Contains(callback));
|
assert(!callbacks.Contains(callback));
|
||||||
|
|
||||||
auto &c = callbacks.Add(callback, *this);
|
auto &c = callbacks.Add(callback, *this, true);
|
||||||
if (!c.Open(context, path, flags, error)) {
|
if (!c.Open(context, path, flags, error)) {
|
||||||
callbacks.Remove(c);
|
callbacks.Remove(c);
|
||||||
return false;
|
return false;
|
||||||
|
@ -172,7 +180,7 @@ NfsConnection::Stat(struct nfsfh *fh, NfsCallback &callback, Error &error)
|
||||||
{
|
{
|
||||||
assert(!callbacks.Contains(callback));
|
assert(!callbacks.Contains(callback));
|
||||||
|
|
||||||
auto &c = callbacks.Add(callback, *this);
|
auto &c = callbacks.Add(callback, *this, false);
|
||||||
if (!c.Stat(context, fh, error)) {
|
if (!c.Stat(context, fh, error)) {
|
||||||
callbacks.Remove(c);
|
callbacks.Remove(c);
|
||||||
return false;
|
return false;
|
||||||
|
@ -188,7 +196,7 @@ NfsConnection::Read(struct nfsfh *fh, uint64_t offset, size_t size,
|
||||||
{
|
{
|
||||||
assert(!callbacks.Contains(callback));
|
assert(!callbacks.Contains(callback));
|
||||||
|
|
||||||
auto &c = callbacks.Add(callback, *this);
|
auto &c = callbacks.Add(callback, *this, false);
|
||||||
if (!c.Read(context, fh, offset, size, error)) {
|
if (!c.Read(context, fh, offset, size, error)) {
|
||||||
callbacks.Remove(c);
|
callbacks.Remove(c);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -39,11 +39,21 @@ class NfsConnection : SocketMonitor, DeferredMonitor {
|
||||||
class CancellableCallback : public CancellablePointer<NfsCallback> {
|
class CancellableCallback : public CancellablePointer<NfsCallback> {
|
||||||
NfsConnection &connection;
|
NfsConnection &connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a nfs_open_async() operation? If yes, then
|
||||||
|
* we need to call nfs_close_async() on the new file
|
||||||
|
* handle as soon as the callback is invoked
|
||||||
|
* successfully.
|
||||||
|
*/
|
||||||
|
const bool open;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CancellableCallback(NfsCallback &_callback,
|
explicit CancellableCallback(NfsCallback &_callback,
|
||||||
NfsConnection &_connection)
|
NfsConnection &_connection,
|
||||||
|
bool _open)
|
||||||
:CancellablePointer<NfsCallback>(_callback),
|
:CancellablePointer<NfsCallback>(_callback),
|
||||||
connection(_connection) {}
|
connection(_connection),
|
||||||
|
open(_open) {}
|
||||||
|
|
||||||
bool Open(nfs_context *context, const char *path, int flags,
|
bool Open(nfs_context *context, const char *path, int flags,
|
||||||
Error &error);
|
Error &error);
|
||||||
|
|
Loading…
Reference in New Issue