From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org, Marek Zawirski <marek.zawirski@gmail.com>
Subject: Re: [EGIT PATCH 4/9] Add a method to listen to changes in any repository
Date: Fri, 11 Jul 2008 04:28:22 +0000 [thread overview]
Message-ID: <20080711042822.GC32633@spearce.org> (raw)
In-Reply-To: <1215729651-26781-5-git-send-email-robin.rosenberg@dewire.com>
Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
> 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 6f78652..dfa3045 100644
> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
> @@ -95,6 +95,7 @@ public class Repository {
> private GitIndex index;
>
> private List<RepositoryListener> listeners = new Vector<RepositoryListener>(); // thread safe
> + static private List<RepositoryListener> allListeners = new Vector<RepositoryListener>(); // thread safe
...
> void fireRefsMaybeChanged() {
> if (refs.lastRefModification != refs.lastNotifiedRefModification) {
> refs.lastNotifiedRefModification = refs.lastRefModification;
> final RefsChangedEvent event = new RefsChangedEvent(this);
> - for (final RepositoryListener l :
> - listeners.toArray(new RepositoryListener[listeners.size()])) {
> + List<RepositoryListener> all = new ArrayList<RepositoryListener>(
> + listeners);
> + all.addAll(allListeners);
> + for (final RepositoryListener l : all) {
> l.refsChanged(event);
I don't think this pattern is thread-safe like you think it is.
Adding (or removing) an allListener while you are trying
to copy the allListener collection for delivery can cause a
ConcurrentModificationException.
The preimage here is not even correct because toArray locks the
vector and will grow the input array if it was too small, but it
nulls out the later entries if the array was too large. Thus you
can NPE inside of the fire loop.
The only safe way to do this is to lock the collection while you copy
it into an array or list, then later iterate that to do the delivery.
Both of the fire implemenations in this patch have this issue. :-|
--
Shawn.
next prev parent reply other threads:[~2008-07-11 4:29 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-10 22:40 [EGIT PATCH 0/9] Repository change listeners Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 1/9] Create a listener structure for changes to refs and index Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 2/9] Cached modification times for symbolic refs too Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 3/9] Connect the history page to the refs update subscription mechanism Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 4/9] Add a method to listen to changes in any repository Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 5/9] Add a job to periodically scan for repository changes Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 6/9] Change GitHistoryPage to listen on any repository Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 7/9] Add a job to refresh projects when the index changes Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 8/9] Make git dectected changes depend on the automatic refresh setting Robin Rosenberg
2008-07-10 22:40 ` [EGIT PATCH 9/9] Attach the resource decorator to the repository change event mechanism Robin Rosenberg
2008-07-11 4:33 ` [EGIT PATCH 7/9] Add a job to refresh projects when the index changes Shawn O. Pearce
2008-07-11 9:32 ` [PATCH 7/7] " Robin Rosenberg
2008-07-11 4:28 ` Shawn O. Pearce [this message]
2008-07-11 9:48 ` [PATCH 4/4] Add a method to listen to changes in any repository Robin Rosenberg
2008-07-11 12:24 ` jgit (was: [PATCH 4/4] Add a method...) Andreas Ericsson
2008-07-11 12:24 ` Robin Rosenberg
2008-07-11 4:22 ` [EGIT PATCH 1/9] Create a listener structure for changes to refs and index Shawn O. Pearce
2008-07-11 9:27 ` [PATCH] " Robin Rosenberg
2008-07-11 5:26 ` [EGIT PATCH 0/9] Repository change listeners Shawn O. Pearce
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=20080711042822.GC32633@spearce.org \
--to=spearce@spearce.org \
--cc=git@vger.kernel.org \
--cc=marek.zawirski@gmail.com \
--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).