Re: [Pydev-cvs] org.python.pydev/src/org/python/pydev/outline PyOutlinePage.java, 1.25, 1.26 Outli
Brought to you by:
fabioz
|
From: Radim K. <ra...@ku...> - 2008-08-22 05:52:26
|
A comment about your synchronization patch:
When I saw it I thought it cannot work. But I was surprised that
autoboxing is so smart that
Integer i; i++;
causes conversion from Integer to int, increment and then (even if it
is postfix increment) conversion back to Integer and storing to i
variable. So far so good.
2nd idea: why volatile when every access is done inside this
synchronized block?
And now there is a reason why it does not work as you probably expect:
Integer is an immutable object after each ++/-- you have another
instance to synchronize on. So there can be more threads inside this
synchronized block than one. For example if linkLevel is 0 one thread
can start relinkAll and increment it, second thread calls unlinkAll
and executes remove*() before add*() is called in 1st thread because
it now sees different object assgned to linkLevel (and it volatile to
inrease the chance that it will happen).
Use
private final Object lock = new Object();
private int linkLevel = 1
+ synchronized(lock)
Without the need for 1.4 compatibility you could also use
AtomicInteger.{increment|decrement}AndGet()
Yet another reason why your patch is bad: if you read
http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7
carefully you will see that the intent is to provide the same instance
for the same primitive values. Synchronizing on a publicly known
object is wrong. If someone else starts to do the same at some other
random place in the codebase you can get interesting contention
(better) or deadlocks (worse).
-Radim
On Thu, Aug 21, 2008 at 1:56 PM, Fabio Zadrozny
<fa...@us...> wrote:
> Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/outline
> In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19176/src/org/python/pydev/outline
>
> Modified Files:
> PyOutlinePage.java OutlineLinkWithEditorAction.java
> Log Message:
> Minor changes for console / possible race condition on linking with outline page.
>
> Index: PyOutlinePage.java
> ===================================================================
> RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/outline/PyOutlinePage.java,v
> retrieving revision 1.25
> retrieving revision 1.26
> ***************
> *** 299,313 ****
> }
>
> void unlinkAll() {
> ! removeSelectionChangedListener(selectionListener);
> ! if(linkWithEditor != null){
> ! linkWithEditor.unlink();
> }
> }
>
> void relinkAll() {
> ! addSelectionChangedListener(selectionListener);
> ! if(linkWithEditor != null){
> ! linkWithEditor.relink();
> }
> }
> --- 305,343 ----
> }
>
> + /**
> + * Used to hold a link level to know when it should be unlinked or relinked, as calls can be 'cascaded'
> + */
> + private volatile Integer linkLevel = 1;
> +
> + /**
> + * Stops listening to changes (the linkLevel is used so that multiple unlinks can be called and later
> + * multiple relinks should be used)
> + */
> void unlinkAll() {
> ! synchronized (linkLevel) {
> ! linkLevel--;
> ! if(linkLevel == 0){
> ! removeSelectionChangedListener(selectionListener);
> ! if(linkWithEditor != null){
> ! linkWithEditor.unlink();
> ! }
> ! }
> }
> }
>
> + /**
> + * Starts listening to changes again if the number of relinks matches the number of unlinks
> + */
> void relinkAll() {
> ! synchronized (linkLevel) {
> ! linkLevel++;
> ! if(linkLevel == 1){
> ! addSelectionChangedListener(selectionListener);
> ! if(linkWithEditor != null){
> ! linkWithEditor.relink();
> ! }
> ! }else if(linkLevel > 1){
> ! throw new RuntimeException("Error: relinking without unlinking 1st");
> ! }
> }
> }
>
> Index: OutlineLinkWithEditorAction.java
> ===================================================================
> RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/outline/OutlineLinkWithEditorAction.java,v
> retrieving revision 1.8
> retrieving revision 1.9
> diff -C2 -d -r1.8 -r1.9
> *** OutlineLinkWithEditorAction.java 5 Feb 2008 23:11:12 -0000 1.8
> --- OutlineLinkWithEditorAction.java 21 Aug 2008 20:56:28 -0000 1.9
> ***************
> *** 25,28 ****
> --- 25,34 ----
> * editor.
> *
> + * Design notes:
> + * It's linked on the constructor and unlinked in the destructor.
> + *
> + * It considers that it's always linked, even if the action is inactive, but before executing it, a
> + * check is done to see if it's active or not.
> + *
> * @author Fabio
> */
> ***************
> *** 40,43 ****
> --- 46,52 ----
> }
>
> + /**
> + * When called, it STOPS hearing notifications to update the outline when the cursor changes positions.
> + */
> public void unlink() {
> PyEdit edit = pyEdit.get();
> ***************
> *** 47,50 ****
> --- 56,62 ----
> }
>
> + /**
> + * When called, it STARTS hearing notifications to update the outline when the cursor changes positions.
> + */
> public void relink() {
> PyEdit edit = pyEdit.get();
> ***************
> *** 158,161 ****
> --- 170,176 ----
>
>
> + /**
> + * @return The parsed item that should be selected given the startLine passed.
> + */
> private ParsedItem findSel(ParsedItem r, int startLine) {
> ParsedItem prev = null;
>
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Pydev-cvs mailing list
> Pyd...@li...
> https://lists.sourceforge.net/lists/listinfo/pydev-cvs
>
|