From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org
Subject: [JGIT PATCH 06/13] Make Repository thread-safe
Date: Mon, 22 Dec 2008 16:27:16 -0800 [thread overview]
Message-ID: <1229992043-1053-7-git-send-email-spearce@spearce.org> (raw)
In-Reply-To: <1229992043-1053-6-git-send-email-spearce@spearce.org>
The Repository class itself is now thread-safe. Thread safety is
ensured by copying values onto the caller stack prior to use.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../src/org/spearce/jgit/lib/Repository.java | 75 ++++++++++++-------
1 files changed, 47 insertions(+), 28 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index ff36a3d..89ad991 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -46,6 +46,7 @@
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -79,20 +80,22 @@
* </ul>
* </li>
* </ul>
- *
+ * <p>
+ * This class is thread-safe.
+ * <p>
* This implementation only handles a subtly undocumented subset of git features.
*
*/
public class Repository {
private final File gitDir;
- private final File[] objectsDirs;
-
private final RepositoryConfig config;
private final RefDatabase refs;
- private PackFile[] packs;
+ private File[] objectDirectoryList;
+
+ private PackFile[] packFileList;
private GitIndex index;
@@ -111,18 +114,19 @@
public Repository(final File d) throws IOException {
gitDir = d.getAbsoluteFile();
try {
- objectsDirs = readObjectsDirs(FS.resolve(gitDir, "objects"),
- new ArrayList<File>()).toArray(new File[0]);
+ objectDirectoryList = readObjectsDirs(
+ FS.resolve(gitDir, "objects"), new ArrayList<File>())
+ .toArray(new File[0]);
} catch (IOException e) {
IOException ex = new IOException("Cannot find all object dirs for " + gitDir);
ex.initCause(e);
throw ex;
}
refs = new RefDatabase(this);
- packs = new PackFile[0];
+ packFileList = new PackFile[0];
config = new RepositoryConfig(this);
- final boolean isExisting = objectsDirs[0].exists();
+ final boolean isExisting = objectDirectoryList[0].exists();
if (isExisting) {
getConfig().load();
final String repositoryFormatVersion = getConfig().getString(
@@ -138,7 +142,8 @@ public Repository(final File d) throws IOException {
scanForPacks();
}
- private Collection<File> readObjectsDirs(File objectsDir, Collection<File> ret) throws IOException {
+ private static Collection<File> readObjectsDirs(File objectsDir,
+ Collection<File> ret) throws IOException {
ret.add(objectsDir);
final File altFile = FS.resolve(objectsDir, "info/alternates");
if (altFile.exists()) {
@@ -160,7 +165,7 @@ public Repository(final File d) throws IOException {
*
* @throws IOException
*/
- public void create() throws IOException {
+ public synchronized void create() throws IOException {
if (gitDir.exists()) {
throw new IllegalStateException("Repository already exists: "
+ gitDir);
@@ -169,9 +174,9 @@ public void create() throws IOException {
gitDir.mkdirs();
refs.create();
- objectsDirs[0].mkdirs();
- new File(objectsDirs[0], "pack").mkdir();
- new File(objectsDirs[0], "info").mkdir();
+ objectDirectoryList[0].mkdirs();
+ new File(objectDirectoryList[0], "pack").mkdir();
+ new File(objectDirectoryList[0], "info").mkdir();
new File(gitDir, "branches").mkdir();
new File(gitDir, "remotes").mkdir();
@@ -182,6 +187,14 @@ public void create() throws IOException {
getConfig().save();
}
+ private synchronized File[] objectsDirs(){
+ return objectDirectoryList;
+ }
+
+ private synchronized PackFile[] packs(){
+ return packFileList;
+ }
+
/**
* @return GIT_DIR
*/
@@ -193,7 +206,7 @@ public File getDirectory() {
* @return the directory containing the objects owned by this repository.
*/
public File getObjectsDirectory() {
- return objectsDirs[0];
+ return objectsDirs()[0];
}
/**
@@ -217,6 +230,7 @@ public File toFile(final AnyObjectId objectId) {
final String n = objectId.name();
String d=n.substring(0, 2);
String f=n.substring(2);
+ final File[] objectsDirs = objectsDirs();
for (int i=0; i<objectsDirs.length; ++i) {
File ret = new File(new File(objectsDirs[i], d), f);
if (ret.exists())
@@ -231,6 +245,7 @@ public File toFile(final AnyObjectId objectId) {
* known shared repositories.
*/
public boolean hasObject(final AnyObjectId objectId) {
+ final PackFile[] packs = packs();
int k = packs.length;
if (k > 0) {
do {
@@ -271,6 +286,7 @@ public ObjectLoader openObject(final AnyObjectId id)
*/
public ObjectLoader openObject(final WindowCursor curs, final AnyObjectId id)
throws IOException {
+ final PackFile[] packs = packs();
int k = packs.length;
if (k > 0) {
do {
@@ -341,7 +357,7 @@ public ObjectLoader openObject(final WindowCursor curs, final AnyObjectId id)
void openObjectInAllPacks(final AnyObjectId objectId,
final Collection<PackedObjectLoader> resultLoaders,
final WindowCursor curs) throws IOException {
- for (PackFile pack : packs) {
+ for (PackFile pack : packs()) {
final PackedObjectLoader loader = pack.get(curs, objectId);
if (loader != null)
resultLoaders.add(loader);
@@ -766,11 +782,10 @@ public void close() {
closePacks();
}
- void closePacks() {
- for (int k = packs.length - 1; k >= 0; k--) {
- packs[k].close();
- }
- packs = new PackFile[0];
+ synchronized void closePacks() {
+ for (int k = packFileList.length - 1; k >= 0; k--)
+ packFileList[k].close();
+ packFileList = new PackFile[0];
}
/**
@@ -795,11 +810,13 @@ public void openPack(final File pack, final File idx) throws IOException {
throw new IllegalArgumentException("Pack " + pack
+ "does not match index " + idx);
- final PackFile[] cur = packs;
- final PackFile[] arr = new PackFile[cur.length + 1];
- System.arraycopy(cur, 0, arr, 1, cur.length);
- arr[0] = new PackFile(this, idx, pack);
- packs = arr;
+ synchronized (this) {
+ final PackFile[] cur = packFileList;
+ final PackFile[] arr = new PackFile[cur.length + 1];
+ System.arraycopy(cur, 0, arr, 1, cur.length);
+ arr[0] = new PackFile(this, idx, pack);
+ packFileList = arr;
+ }
}
/**
@@ -808,11 +825,13 @@ public void openPack(final File pack, final File idx) throws IOException {
*/
public void scanForPacks() {
final ArrayList<PackFile> p = new ArrayList<PackFile>();
- for (int i=0; i<objectsDirs.length; ++i)
- scanForPacks(new File(objectsDirs[i], "pack"), p);
+ for (final File d : objectsDirs())
+ scanForPacks(new File(d, "pack"), p);
final PackFile[] arr = new PackFile[p.size()];
p.toArray(arr);
- packs = arr;
+ synchronized (this) {
+ packFileList = arr;
+ }
}
private void scanForPacks(final File packDir, Collection<PackFile> packList) {
--
1.6.1.rc4.301.g5497a
next prev parent reply other threads:[~2008-12-23 0:30 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-23 0:27 [JGIT PATCH 00/13] Add receive-pack server side support Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 01/13] Fix invalid "double checked locking" in InflaterCache Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 02/13] Cleanup stupid release of the cached Inflater in IndexPack Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 03/13] Cache an Inflater inside a WindowCursor and reuse it as much as possible Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 04/13] Make RefDatabase thread-safe Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 05/13] Make PackFile thread-safe Shawn O. Pearce
2008-12-23 0:27 ` Shawn O. Pearce [this message]
2008-12-23 0:27 ` [JGIT PATCH 07/13] Don't open a PackFile multiple times on scanForPacks Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 08/13] Expose RepositoryConfig.getBoolean so applications can use it Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 09/13] Add AnyObjectId.copyTo(StringBuilder) Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 10/13] Add compare-and-swap semantics to RefUpdate Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 11/13] Allow null new ObjectId during RefUpdate.delete Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 12/13] Implement the git-receive-pack process in Java Shawn O. Pearce
2008-12-23 0:27 ` [JGIT PATCH 13/13] Add basic git daemon support to publish receive-pack Shawn O. Pearce
2009-01-03 23:48 ` Robin Rosenberg
2009-01-05 2:46 ` [PATCH] Permit a wider range of repository names in jgit daemon requests Shawn O. Pearce
2009-01-05 23:07 ` Robin Rosenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1229992043-1053-7-git-send-email-spearce@spearce.org \
--to=spearce@spearce.org \
--cc=git@vger.kernel.org \
--cc=robin.rosenberg@dewire.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).