lib/nfs/Connection: create the nfs_context in the constructor

Another lifetime simplification.
This commit is contained in:
Max Kellermann 2024-05-06 16:53:04 +02:00
parent 4139024b3d
commit d61c83ace8
8 changed files with 43 additions and 32 deletions

View File

@ -175,12 +175,16 @@ events_to_libnfs(unsigned i) noexcept
NfsConnection::NfsConnection(EventLoop &_loop,
std::string_view _server,
std::string_view _export_name) noexcept
std::string_view _export_name)
:socket_event(_loop, BIND_THIS_METHOD(OnSocketReady)),
defer_new_lease(_loop, BIND_THIS_METHOD(RunDeferred)),
mount_timeout_event(_loop, BIND_THIS_METHOD(OnMountTimeout)),
server(_server), export_name(_export_name),
context(nullptr) {}
context(nfs_init_context())
{
if (context == nullptr)
throw std::runtime_error{"nfs_init_context() failed"};
}
NfsConnection::~NfsConnection() noexcept
{
@ -189,11 +193,10 @@ NfsConnection::~NfsConnection() noexcept
assert(active_leases.empty());
assert(callbacks.IsEmpty());
assert(deferred_close.empty());
assert(context != nullptr);
if (context != nullptr) {
PrepareDestroyContext();
nfs_destroy_context(context);
}
socket_event.ReleaseSocket();
nfs_destroy_context(context);
}
void
@ -348,7 +351,6 @@ inline void
NfsConnection::InternalClose(struct nfsfh *fh) noexcept
{
assert(GetEventLoop().IsInside());
assert(context != nullptr);
assert(fh != nullptr);
nfs_close_async(context, fh, DummyCallback, nullptr);
@ -374,7 +376,6 @@ void
NfsConnection::PrepareDestroyContext() noexcept
{
assert(GetEventLoop().IsInside());
assert(context != nullptr);
#ifndef NDEBUG
assert(!in_destroy);
@ -410,7 +411,6 @@ NfsConnection::DeferClose(struct nfsfh *fh) noexcept
assert(GetEventLoop().IsInside());
assert(in_event);
assert(in_service);
assert(context != nullptr);
assert(fh != nullptr);
deferred_close.push_front(fh);
@ -420,7 +420,6 @@ void
NfsConnection::ScheduleSocket() noexcept
{
assert(GetEventLoop().IsInside());
assert(context != nullptr);
const int which_events = nfs_which_events(context);
@ -449,7 +448,6 @@ inline int
NfsConnection::Service(unsigned flags) noexcept
{
assert(GetEventLoop().IsInside());
assert(context != nullptr);
#ifndef NDEBUG
assert(!in_event);
@ -462,7 +460,6 @@ NfsConnection::Service(unsigned flags) noexcept
int result = nfs_service(context, events_to_libnfs(flags));
#ifndef NDEBUG
assert(context != nullptr);
assert(in_service);
in_service = false;
#endif
@ -523,7 +520,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
return;
}
assert(context != nullptr);
assert(nfs_get_fd(context) >= 0);
#ifndef NDEBUG
@ -531,8 +527,7 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
in_event = false;
#endif
if (context != nullptr)
ScheduleSocket();
ScheduleSocket();
}
inline void
@ -568,13 +563,8 @@ inline void
NfsConnection::MountInternal()
{
assert(GetEventLoop().IsInside());
assert(context == nullptr);
assert(mount_state == MountState::INITIAL);
context = nfs_init_context();
if (context == nullptr)
throw std::runtime_error("nfs_init_context() failed");
postponed_mount_error = std::exception_ptr();
mount_state = MountState::WAITING;

View File

@ -82,7 +82,7 @@ class NfsConnection {
const std::string server, export_name;
nfs_context *context;
nfs_context *const context;
using LeaseList = IntrusiveList<NfsLease>;
LeaseList new_leases, active_leases;
@ -126,10 +126,13 @@ class NfsConnection {
#endif
public:
/**
* Throws on error.
*/
[[gnu::nonnull]]
NfsConnection(EventLoop &_loop,
std::string_view _server,
std::string_view _export_name) noexcept;
std::string_view _export_name);
/**
* Must be run from EventLoop's thread.

View File

@ -266,8 +266,13 @@ NfsFileReader::OnDeferredOpen() noexcept
{
assert(state == State::DEFER);
state = State::MOUNT;
try {
connection = &nfs_get_connection(server, export_name);
} catch (...) {
OnNfsFileError(std::current_exception());
return;
}
connection = &nfs_get_connection(server, export_name);
connection->AddLease(*this);
state = State::MOUNT;
}

View File

@ -41,7 +41,7 @@ nfs_get_event_loop() noexcept
NfsConnection &
nfs_get_connection(std::string_view server,
std::string_view export_name) noexcept
std::string_view export_name)
{
assert(in_use > 0);

View File

@ -21,7 +21,10 @@ nfs_finish() noexcept;
EventLoop &
nfs_get_event_loop() noexcept;
[[gnu::pure]]
/**
* Throws on error.
*/
[[nodiscard]]
NfsConnection &
nfs_get_connection(std::string_view server,
std::string_view export_name) noexcept;
std::string_view export_name);

View File

@ -21,7 +21,7 @@ class NfsManager::ManagedConnection final
public:
ManagedConnection(NfsManager &_manager, EventLoop &_loop,
std::string_view _server,
std::string_view _export_name) noexcept
std::string_view _export_name)
:NfsConnection(_loop, _server, _export_name),
manager(_manager) {}
@ -55,7 +55,7 @@ NfsManager::~NfsManager() noexcept
}
NfsConnection &
NfsManager::GetConnection(std::string_view server, std::string_view export_name) noexcept
NfsManager::GetConnection(std::string_view server, std::string_view export_name)
{
assert(GetEventLoop().IsInside());

View File

@ -41,9 +41,12 @@ public:
return idle_event.GetEventLoop();
}
[[gnu::pure]]
/**
* Throws on error.
*/
[[nodiscard]]
NfsConnection &GetConnection(std::string_view server,
std::string_view export_name) noexcept;
std::string_view export_name);
private:
void ScheduleDelete(ManagedConnection &c) noexcept;

View File

@ -141,7 +141,14 @@ private:
assert(state != State::READY);
assert(GetEventLoop().IsInside());
connection = &nfs_get_connection(server, export_name);
try {
connection = &nfs_get_connection(server, export_name);
} catch (...) {
SetState(State::DELAY, std::current_exception());
reconnect_timer.Schedule(std::chrono::minutes(10));
return;
}
connection->AddLease(*this);
SetState(State::CONNECTING);