lib/nfs/Connection: implement mount timeout
This commit is contained in:
		
							
								
								
									
										1
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								NEWS
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ ver 0.19.7 (not yet released) | ||||
|   - nfs: fix crash while canceling a failing file open operation | ||||
|   - nfs: fix memory leak on connection failure | ||||
|   - nfs: fix reconnect after mount failure | ||||
|   - nfs: implement mount timeout (60 seconds) | ||||
| * playlist | ||||
|   - don't skip non-existent songs in "listplaylist" | ||||
| * fix memory allocator bug on Windows | ||||
|   | ||||
| @@ -34,6 +34,8 @@ extern "C" { | ||||
|  | ||||
| #include <poll.h> /* for POLLIN, POLLOUT */ | ||||
|  | ||||
| static constexpr unsigned NFS_MOUNT_TIMEOUT = 60; | ||||
|  | ||||
| inline bool | ||||
| NfsConnection::CancellableCallback::Stat(nfs_context *ctx, | ||||
| 					 const char *path, | ||||
| @@ -379,6 +381,11 @@ NfsConnection::DestroyContext() | ||||
| 	in_destroy = true; | ||||
| #endif | ||||
|  | ||||
| 	if (!mount_finished) { | ||||
| 		assert(TimeoutMonitor::IsActive()); | ||||
| 		TimeoutMonitor::Cancel(); | ||||
| 	} | ||||
|  | ||||
| 	/* cancel pending DeferredMonitor that was scheduled to notify | ||||
| 	   new leases */ | ||||
| 	DeferredMonitor::Cancel(); | ||||
| @@ -528,6 +535,9 @@ NfsConnection::MountCallback(int status, gcc_unused nfs_context *nfs, | ||||
|  | ||||
| 	mount_finished = true; | ||||
|  | ||||
| 	assert(TimeoutMonitor::IsActive() || in_destroy); | ||||
| 	TimeoutMonitor::Cancel(); | ||||
|  | ||||
| 	if (status < 0) { | ||||
| 		postponed_mount_error.Format(nfs_domain, status, | ||||
| 					     "nfs_mount_async() failed: %s", | ||||
| @@ -560,6 +570,8 @@ NfsConnection::MountInternal(Error &error) | ||||
| 	postponed_mount_error.Clear(); | ||||
| 	mount_finished = false; | ||||
|  | ||||
| 	TimeoutMonitor::ScheduleSeconds(NFS_MOUNT_TIMEOUT); | ||||
|  | ||||
| #ifndef NDEBUG | ||||
| 	in_service = false; | ||||
| 	in_event = false; | ||||
| @@ -620,6 +632,18 @@ NfsConnection::BroadcastError(Error &&error) | ||||
| 	BroadcastMountError(std::move(error)); | ||||
| } | ||||
|  | ||||
| void | ||||
| NfsConnection::OnTimeout() | ||||
| { | ||||
| 	assert(GetEventLoop().IsInside()); | ||||
| 	assert(!mount_finished); | ||||
|  | ||||
| 	mount_finished = true; | ||||
| 	DestroyContext(); | ||||
|  | ||||
| 	BroadcastMountError(Error(nfs_domain, "Mount timeout")); | ||||
| } | ||||
|  | ||||
| void | ||||
| NfsConnection::RunDeferred() | ||||
| { | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "Lease.hxx" | ||||
| #include "Cancellable.hxx" | ||||
| #include "event/SocketMonitor.hxx" | ||||
| #include "event/TimeoutMonitor.hxx" | ||||
| #include "event/DeferredMonitor.hxx" | ||||
| #include "util/Error.hxx" | ||||
|  | ||||
| @@ -40,7 +41,7 @@ class NfsCallback; | ||||
| /** | ||||
|  * An asynchronous connection to a NFS server. | ||||
|  */ | ||||
| class NfsConnection : SocketMonitor, DeferredMonitor { | ||||
| class NfsConnection : SocketMonitor, TimeoutMonitor, DeferredMonitor { | ||||
| 	class CancellableCallback : public CancellablePointer<NfsCallback> { | ||||
| 		NfsConnection &connection; | ||||
|  | ||||
| @@ -142,7 +143,8 @@ public: | ||||
| 	gcc_nonnull_all | ||||
| 	NfsConnection(EventLoop &_loop, | ||||
| 		      const char *_server, const char *_export_name) | ||||
| 		:SocketMonitor(_loop), DeferredMonitor(_loop), | ||||
| 		:SocketMonitor(_loop), TimeoutMonitor(_loop), | ||||
| 		 DeferredMonitor(_loop), | ||||
| 		 server(_server), export_name(_export_name), | ||||
| 		 context(nullptr) {} | ||||
|  | ||||
| @@ -227,6 +229,9 @@ private: | ||||
| 	/* virtual methods from SocketMonitor */ | ||||
| 	virtual bool OnSocketReady(unsigned flags) override; | ||||
|  | ||||
| 	/* virtual methods from TimeoutMonitor */ | ||||
| 	void OnTimeout() final; | ||||
|  | ||||
| 	/* virtual methods from DeferredMonitor */ | ||||
| 	virtual void RunDeferred() override; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann