MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / InitializeServerPipe

Function InitializeServerPipe

Source/Tools/FEXServer/ProcessPipe.cpp:85–181  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

83}
84
85bool InitializeServerPipe() {
86 auto ServerFolder = FEXServerClient::GetServerLockFolder();
87
88 std::error_code ec {};
89 if (!std::filesystem::exists(ServerFolder, ec)) {
90 // Doesn't exist, create the the folder as a user convenience
91 if (!std::filesystem::create_directories(ServerFolder, ec)) {
92 LogMan::Msg::EFmt("Couldn't create server pipe folder at: {}", ServerFolder);
93 return false;
94 }
95 }
96
97 auto ServerLockPath = FEXServerClient::GetServerLockFile();
98
99 // Now this is some tricky locking logic to ensure that we only ever have one server running
100 // The logic is as follows:
101 // - Try to make the lock file
102 // - If Exists then check to see if it is a stale handle
103 // - Stale checking means opening the file that we know exists
104 // - Then we try getting a write lock
105 // - If we fail to get the write lock, then leave
106 // - Otherwise continue down the codepath and degrade to read lock
107 // - Else try to acquire a write lock to ensure only one FEXServer exists
108 //
109 // - Once a write lock is acquired, downgrade it to a read lock
110 // - This ensures that future FEXServers won't race to create multiple read locks
111 int Ret = open(ServerLockPath.c_str(), O_RDWR | O_CREAT | O_CLOEXEC | O_EXCL, USER_PERMS);
112 ServerLockFD = Ret;
113
114 if (Ret == -1 && errno == EEXIST) {
115 // If the lock exists then it might be a stale connection.
116 // Check the lock status to see if another process is still alive.
117 ServerLockFD = open(ServerLockPath.c_str(), O_RDWR | O_CLOEXEC, USER_PERMS);
118 if (ServerLockFD != -1) {
119 // Now that we have opened the file, try to get a write lock.
120 flock lk {
121 .l_type = F_WRLCK,
122 .l_whence = SEEK_SET,
123 .l_start = 0,
124 .l_len = 0,
125 };
126 Ret = fcntl(ServerLockFD, F_SETLK, &lk);
127
128 if (Ret != -1) {
129 // Write lock was gained, we can now continue onward.
130 } else {
131 // We couldn't get a write lock, this means that another process already owns a lock on the lock
132 close(ServerLockFD);
133 ServerLockFD = -1;
134 return false;
135 }
136 } else {
137 // File couldn't get opened even though it existed?
138 // Must have raced something here.
139 return false;
140 }
141 } else if (Ret == -1) {
142 // Unhandled error.

Callers 1

mainFunction · 0.85

Calls 4

GetServerLockFolderFunction · 0.85
EFmtFunction · 0.85
GetServerLockFileFunction · 0.85
closeFunction · 0.85

Tested by

no test coverage detected