@@ -92,6 +92,28 @@ public void Mount(EventLevel verbosity, Keywords keywords)
9292 {
9393 this . currentState = MountState . Mounting ;
9494
95+ string mountLockPath = Path . Combine ( this . enlistment . DotGVFSRoot , GVFSConstants . DotGVFS . MountLock ) ;
96+ using ( FileBasedLock mountLock = GVFSPlatform . Instance . CreateFileBasedLock (
97+ new PhysicalFileSystem ( ) ,
98+ this . tracer ,
99+ mountLockPath ) )
100+ {
101+ if ( ! mountLock . TryAcquireLock ( out Exception lockException ) )
102+ {
103+ if ( lockException is IOException )
104+ {
105+ this . FailMountAndExit ( ReturnCode . MountAlreadyRunning , "Mount: Another mount process is already running." ) ;
106+ }
107+
108+ this . FailMountAndExit ( "Mount: Failed to acquire mount lock: {0}" , lockException . Message ) ;
109+ }
110+
111+ this . MountWithLockAcquired ( verbosity , keywords ) ;
112+ }
113+ }
114+
115+ private void MountWithLockAcquired ( EventLevel verbosity , Keywords keywords )
116+ {
95117 // Start auth + config query immediately — these are network-bound and don't
96118 // depend on repo metadata or cache paths. Every millisecond of network latency
97119 // we can overlap with local I/O is a win.
@@ -303,6 +325,11 @@ private NamedPipeServer StartNamedPipe()
303325 }
304326
305327 private void FailMountAndExit ( string error , params object [ ] args )
328+ {
329+ this . FailMountAndExit ( ReturnCode . GenericError , error , args ) ;
330+ }
331+
332+ private void FailMountAndExit ( ReturnCode returnCode , string error , params object [ ] args )
306333 {
307334 this . currentState = MountState . MountFailed ;
308335
@@ -319,7 +346,7 @@ private void FailMountAndExit(string error, params object[] args)
319346 this . fileSystemCallbacks = null ;
320347 }
321348
322- Environment . Exit ( ( int ) ReturnCode . GenericError ) ;
349+ Environment . Exit ( ( int ) returnCode ) ;
323350 }
324351
325352 private T CreateOrReportAndExit < T > ( Func < T > factory , string reportMessage )
0 commit comments