Skip to content

Commit 7b70850

Browse files
kivikakkchrisd8088
authored andcommitted
refactor MacFileBasedLock and LinuxFileBasedLock
1 parent 435123f commit 7b70850

File tree

3 files changed

+141
-188
lines changed

3 files changed

+141
-188
lines changed
Lines changed: 10 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,31 @@
11
using GVFS.Common;
22
using GVFS.Common.FileSystem;
33
using GVFS.Common.Tracing;
4+
using GVFS.Platform.POSIX;
45
using System;
56
using System.IO;
67
using System.Runtime.InteropServices;
78

89
namespace GVFS.Platform.Linux
910
{
10-
public class LinuxFileBasedLock : FileBasedLock
11+
public class LinuxFileBasedLock : POSIXFileBasedLock
1112
{
12-
private int lockFileDescriptor;
13-
1413
public LinuxFileBasedLock(
1514
PhysicalFileSystem fileSystem,
1615
ITracer tracer,
1716
string lockPath)
1817
: base(fileSystem, tracer, lockPath)
1918
{
20-
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
2119
}
2220

23-
public override bool TryAcquireLock()
24-
{
25-
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
26-
{
27-
this.FileSystem.CreateDirectory(Path.GetDirectoryName(this.LockPath));
28-
29-
this.lockFileDescriptor = NativeMethods.Open(
30-
this.LockPath,
31-
NativeMethods.OpenCreate | NativeMethods.OpenWriteOnly,
32-
NativeMethods.FileMode644);
33-
34-
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
35-
{
36-
int errno = Marshal.GetLastWin32Error();
37-
EventMetadata metadata = this.CreateEventMetadata(errno);
38-
this.Tracer.RelatedWarning(
39-
metadata,
40-
$"{nameof(LinuxFileBasedLock)}.{nameof(this.TryAcquireLock)}: Failed to open lock file");
41-
42-
return false;
43-
}
44-
}
45-
46-
if (NativeMethods.FLock(this.lockFileDescriptor, NativeMethods.LockEx | NativeMethods.LockNb) != 0)
47-
{
48-
int errno = Marshal.GetLastWin32Error();
49-
if (errno != NativeMethods.EIntr && errno != NativeMethods.EWouldBlock)
50-
{
51-
EventMetadata metadata = this.CreateEventMetadata(errno);
52-
this.Tracer.RelatedWarning(
53-
metadata,
54-
$"{nameof(LinuxFileBasedLock)}.{nameof(this.TryAcquireLock)}: Unexpected error when locking file");
55-
}
56-
57-
return false;
58-
}
59-
60-
return true;
61-
}
62-
63-
public override void Dispose()
64-
{
65-
if (this.lockFileDescriptor != NativeMethods.InvalidFileDescriptor)
66-
{
67-
if (NativeMethods.Close(this.lockFileDescriptor) != 0)
68-
{
69-
// Failures of close() are logged for diagnostic purposes only.
70-
// It's possible that errors from a previous operation (e.g. write(2))
71-
// are only reported in close(). We should *not* retry the close() if
72-
// it fails since it may cause a re-used file descriptor from another
73-
// thread to be closed.
21+
protected override int EIntr => NativeMethods.EIntr;
22+
protected override int EWouldBlock => NativeMethods.EWouldBlock;
7423

75-
int errno = Marshal.GetLastWin32Error();
76-
EventMetadata metadata = this.CreateEventMetadata(errno);
77-
this.Tracer.RelatedWarning(
78-
metadata,
79-
$"{nameof(LinuxFileBasedLock)}.{nameof(this.Dispose)}: Error when closing lock fd");
80-
}
81-
82-
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
83-
}
84-
}
85-
86-
private EventMetadata CreateEventMetadata(int errno = 0)
87-
{
88-
EventMetadata metadata = new EventMetadata();
89-
metadata.Add("Area", nameof(LinuxFileBasedLock));
90-
metadata.Add(nameof(this.LockPath), this.LockPath);
91-
if (errno != 0)
92-
{
93-
metadata.Add(nameof(errno), errno);
94-
}
95-
96-
return metadata;
97-
}
24+
protected override int CreateFile(string path) =>
25+
NativeMethods.Open(
26+
path,
27+
NativeMethods.OpenCreate | NativeMethods.OpenWriteOnly,
28+
NativeMethods.FileMode644);
9829

9930
private static class NativeMethods
10031
{
@@ -111,23 +42,10 @@ private static class NativeMethods
11142
// #define EWOULDBLOCK EAGAIN /* Operation would block */
11243
public const int EWouldBlock = 11;
11344

114-
public const int LockSh = 1; // #define LOCK_SH 1 /* shared lock */
115-
public const int LockEx = 2; // #define LOCK_EX 2 /* exclusive lock */
116-
public const int LockNb = 4; // #define LOCK_NB 4 /* don't block when locking */
117-
public const int LockUn = 8; // #define LOCK_UN 8 /* unlock */
118-
119-
public const int InvalidFileDescriptor = -1;
120-
12145
public static readonly uint FileMode644 = Convert.ToUInt32("644", 8);
12246

12347
[DllImport("libc", EntryPoint = "open", SetLastError = true)]
124-
public static extern int Open(string pathname, int flags, uint mode);
125-
126-
[DllImport("libc", EntryPoint = "close", SetLastError = true)]
127-
public static extern int Close(int fd);
128-
129-
[DllImport("libc", EntryPoint = "flock", SetLastError = true)]
130-
public static extern int FLock(int fd, int operation);
48+
public static extern int Open(string path, int flags, uint mode);
13149
}
13250
}
13351
}
Lines changed: 14 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,31 @@
11
using GVFS.Common;
22
using GVFS.Common.FileSystem;
33
using GVFS.Common.Tracing;
4+
using GVFS.Platform.POSIX;
45
using System;
56
using System.IO;
6-
using System.Runtime.InteropServices;
7-
7+
using System.Runtime.InteropServices;
8+
89
namespace GVFS.Platform.Mac
910
{
10-
public class MacFileBasedLock : FileBasedLock
11+
public class MacFileBasedLock : POSIXFileBasedLock
1112
{
12-
private int lockFileDescriptor;
13-
1413
public MacFileBasedLock(
1514
PhysicalFileSystem fileSystem,
1615
ITracer tracer,
1716
string lockPath)
1817
: base(fileSystem, tracer, lockPath)
1918
{
20-
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
21-
}
22-
23-
public override bool TryAcquireLock()
24-
{
25-
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
26-
{
27-
this.FileSystem.CreateDirectory(Path.GetDirectoryName(this.LockPath));
28-
29-
this.lockFileDescriptor = NativeMethods.Open(
30-
this.LockPath,
31-
NativeMethods.OpenCreate | NativeMethods.OpenWriteOnly,
32-
NativeMethods.FileMode644);
33-
34-
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
35-
{
36-
int errno = Marshal.GetLastWin32Error();
37-
EventMetadata metadata = this.CreateEventMetadata(errno);
38-
this.Tracer.RelatedWarning(
39-
metadata,
40-
$"{nameof(MacFileBasedLock)}.{nameof(this.TryAcquireLock)}: Failed to open lock file");
41-
42-
return false;
43-
}
44-
}
45-
46-
if (NativeMethods.FLock(this.lockFileDescriptor, NativeMethods.LockEx | NativeMethods.LockNb) != 0)
47-
{
48-
int errno = Marshal.GetLastWin32Error();
49-
if (errno != NativeMethods.EIntr && errno != NativeMethods.EWouldBlock)
50-
{
51-
EventMetadata metadata = this.CreateEventMetadata(errno);
52-
this.Tracer.RelatedWarning(
53-
metadata,
54-
$"{nameof(MacFileBasedLock)}.{nameof(this.TryAcquireLock)}: Unexpected error when locking file");
55-
}
56-
57-
return false;
58-
}
59-
60-
return true;
61-
}
62-
63-
public override void Dispose()
64-
{
65-
if (this.lockFileDescriptor != NativeMethods.InvalidFileDescriptor)
66-
{
67-
if (NativeMethods.Close(this.lockFileDescriptor) != 0)
68-
{
69-
// Failures of close() are logged for diagnostic purposes only.
70-
// It's possible that errors from a previous operation (e.g. write(2))
71-
// are only reported in close(). We should *not* retry the close() if
72-
// it fails since it may cause a re-used file descriptor from another
73-
// thread to be closed.
74-
75-
int errno = Marshal.GetLastWin32Error();
76-
EventMetadata metadata = this.CreateEventMetadata(errno);
77-
this.Tracer.RelatedWarning(
78-
metadata,
79-
$"{nameof(MacFileBasedLock)}.{nameof(this.Dispose)}: Error when closing lock fd");
80-
}
81-
82-
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
83-
}
8419
}
8520

86-
private EventMetadata CreateEventMetadata(int errno = 0)
87-
{
88-
EventMetadata metadata = new EventMetadata();
89-
metadata.Add("Area", nameof(MacFileBasedLock));
90-
metadata.Add(nameof(this.LockPath), this.LockPath);
91-
if (errno != 0)
92-
{
93-
metadata.Add(nameof(errno), errno);
94-
}
21+
protected override int EIntr => NativeMethods.EIntr;
22+
protected override int EWouldBlock => NativeMethods.EWouldBlock;
9523

96-
return metadata;
97-
}
24+
protected override int CreateFile(string path) =>
25+
NativeMethods.Open(
26+
path,
27+
NativeMethods.OpenCreate | NativeMethods.OpenWriteOnly,
28+
NativeMethods.FileMode644);
9829

9930
private static class NativeMethods
10031
{
@@ -111,23 +42,10 @@ private static class NativeMethods
11142
// #define EWOULDBLOCK EAGAIN /* Operation would block */
11243
public const int EWouldBlock = 35;
11344

114-
public const int LockSh = 1; // #define LOCK_SH 1 /* shared lock */
115-
public const int LockEx = 2; // #define LOCK_EX 2 /* exclusive lock */
116-
public const int LockNb = 4; // #define LOCK_NB 4 /* don't block when locking */
117-
public const int LockUn = 8; // #define LOCK_UN 8 /* unlock */
118-
119-
public const int InvalidFileDescriptor = -1;
45+
public static readonly ushort FileMode644 = Convert.ToUInt16("644", 8);
12046

121-
public static readonly ushort FileMode644 = Convert.ToUInt16("644", 8);
122-
123-
[DllImport("libc", EntryPoint = "open", SetLastError = true)]
124-
public static extern int Open(string pathname, int flags, ushort mode);
125-
126-
[DllImport("libc", EntryPoint = "close", SetLastError = true)]
127-
public static extern int Close(int fd);
128-
129-
[DllImport("libc", EntryPoint = "flock", SetLastError = true)]
130-
public static extern int FLock(int fd, int operation);
47+
[DllImport("libc", EntryPoint = "open", SetLastError = true)]
48+
public static extern int Open(string path, int flags, ushort mode);
13149
}
13250
}
13351
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using GVFS.Common;
2+
using GVFS.Common.FileSystem;
3+
using GVFS.Common.Tracing;
4+
using System;
5+
using System.IO;
6+
using System.Runtime.InteropServices;
7+
8+
namespace GVFS.Platform.POSIX
9+
{
10+
public abstract class POSIXFileBasedLock : FileBasedLock
11+
{
12+
private int lockFileDescriptor;
13+
14+
public POSIXFileBasedLock(
15+
PhysicalFileSystem fileSystem,
16+
ITracer tracer,
17+
string lockPath)
18+
: base(fileSystem, tracer, lockPath)
19+
{
20+
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
21+
}
22+
23+
protected abstract int EIntr { get; }
24+
protected abstract int EWouldBlock { get; }
25+
26+
public override bool TryAcquireLock()
27+
{
28+
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
29+
{
30+
this.FileSystem.CreateDirectory(Path.GetDirectoryName(this.LockPath));
31+
32+
this.lockFileDescriptor = this.CreateFile(this.LockPath);
33+
34+
if (this.lockFileDescriptor == NativeMethods.InvalidFileDescriptor)
35+
{
36+
int errno = Marshal.GetLastWin32Error();
37+
EventMetadata metadata = this.CreateEventMetadata(errno);
38+
this.Tracer.RelatedWarning(
39+
metadata,
40+
$"{nameof(POSIXFileBasedLock)}.{nameof(this.TryAcquireLock)}: Failed to open lock file");
41+
42+
return false;
43+
}
44+
}
45+
46+
if (NativeMethods.FLock(this.lockFileDescriptor, NativeMethods.LockEx | NativeMethods.LockNb) != 0)
47+
{
48+
int errno = Marshal.GetLastWin32Error();
49+
if (errno != this.EIntr && errno != this.EWouldBlock)
50+
{
51+
EventMetadata metadata = this.CreateEventMetadata(errno);
52+
this.Tracer.RelatedWarning(
53+
metadata,
54+
$"{nameof(POSIXFileBasedLock)}.{nameof(this.TryAcquireLock)}: Unexpected error when locking file");
55+
}
56+
57+
return false;
58+
}
59+
60+
return true;
61+
}
62+
63+
public override void Dispose()
64+
{
65+
if (this.lockFileDescriptor != NativeMethods.InvalidFileDescriptor)
66+
{
67+
if (NativeMethods.Close(this.lockFileDescriptor) != 0)
68+
{
69+
// Failures of close() are logged for diagnostic purposes only.
70+
// It's possible that errors from a previous operation (e.g. write(2))
71+
// are only reported in close(). We should *not* retry the close() if
72+
// it fails since it may cause a re-used file descriptor from another
73+
// thread to be closed.
74+
75+
int errno = Marshal.GetLastWin32Error();
76+
EventMetadata metadata = this.CreateEventMetadata(errno);
77+
this.Tracer.RelatedWarning(
78+
metadata,
79+
$"{nameof(POSIXFileBasedLock)}.{nameof(this.Dispose)}: Error when closing lock fd");
80+
}
81+
82+
this.lockFileDescriptor = NativeMethods.InvalidFileDescriptor;
83+
}
84+
}
85+
86+
protected abstract int CreateFile(string path);
87+
88+
private EventMetadata CreateEventMetadata(int errno = 0)
89+
{
90+
EventMetadata metadata = new EventMetadata();
91+
metadata.Add("Area", nameof(POSIXFileBasedLock));
92+
metadata.Add(nameof(this.LockPath), this.LockPath);
93+
if (errno != 0)
94+
{
95+
metadata.Add(nameof(errno), errno);
96+
}
97+
98+
return metadata;
99+
}
100+
101+
private static class NativeMethods
102+
{
103+
public const int LockSh = 1; // #define LOCK_SH 1 /* shared lock */
104+
public const int LockEx = 2; // #define LOCK_EX 2 /* exclusive lock */
105+
public const int LockNb = 4; // #define LOCK_NB 4 /* don't block when locking */
106+
public const int LockUn = 8; // #define LOCK_UN 8 /* unlock */
107+
108+
public const int InvalidFileDescriptor = -1;
109+
110+
[DllImport("libc", EntryPoint = "close", SetLastError = true)]
111+
public static extern int Close(int fd);
112+
113+
[DllImport("libc", EntryPoint = "flock", SetLastError = true)]
114+
public static extern int FLock(int fd, int operation);
115+
}
116+
}
117+
}

0 commit comments

Comments
 (0)