+void File::lock() { doLock(LOCK_EX); }
+bool File::try_lock() { return doTryLock(LOCK_EX); }
+void File::lock_shared() { doLock(LOCK_SH); }
+bool File::try_lock_shared() { return doTryLock(LOCK_SH); }
+
+void File::doLock(int op) {
+ checkUnixError(flockNoInt(fd_, op), "flock() failed (lock)");
+}
+
+bool File::doTryLock(int op) {
+ int r = flockNoInt(fd_, op | LOCK_NB);
+ // flock returns EWOULDBLOCK if already locked
+ if (r == -1 && errno == EWOULDBLOCK) return false;
+ checkUnixError(r, "flock() failed (try_lock)");
+ return true;
+}
+
+void File::unlock() {
+ checkUnixError(flockNoInt(fd_, LOCK_UN), "flock() failed (unlock)");
+}
+void File::unlock_shared() { unlock(); }
+