about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-10-23T10·51+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-10-23T10·51+0000
commit92eea8fc4e7a2e4d6d0dda604ecd22c60367b76e (patch)
treecfaa6f87519fa65e35c49aa64388a2af26ea2602 /src
parentc4e7d324b826d1197a90bf7f4f4b593e406e1087 (diff)
* Fix a race condition in addTextToStore().
Diffstat (limited to 'src')
-rw-r--r--src/libnix/store.cc19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/libnix/store.cc b/src/libnix/store.cc
index e32f403b6ca7..c83316cf6ad5 100644
--- a/src/libnix/store.cc
+++ b/src/libnix/store.cc
@@ -302,16 +302,21 @@ void addTextToStore(const Path & dstPath, const string & s)
 {
     if (!isValidPath(dstPath)) {
 
-        /* !!! locking? -> parallel writes are probably idempotent */
+        PathSet lockPaths;
+        lockPaths.insert(dstPath);
+        PathLocks outputLock(lockPaths);
+
+        if (!isValidPath(dstPath)) {
 
-        AutoCloseFD fd = open(dstPath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
-        if (fd == -1) throw SysError(format("creating store file `%1%'") % dstPath);
+            AutoCloseFD fd = open(dstPath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
+            if (fd == -1) throw SysError(format("creating store file `%1%'") % dstPath);
 
-        writeFull(fd, (unsigned char *) s.c_str(), s.size());
+            writeFull(fd, (unsigned char *) s.c_str(), s.size());
 
-        Transaction txn(nixDB);
-        registerValidPath(txn, dstPath);
-        txn.commit();
+            Transaction txn(nixDB);
+            registerValidPath(txn, dstPath);
+            txn.commit();
+        }
     }
 }