/*******************************************************************************
 * Copyright (c) 2010 Oak Ridge National Laboratory.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package org.csstudio.trends.databrowser3.model;

import java.time.Instant;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.csstudio.javafx.rtplot.data.PlotDataProvider;

/** Base for classes that hold plot samples
 *  in a way accessible as {@link PlotDataProvider}
 *
 *  @author Kay Kasemir
 */
abstract public class PlotSamples implements PlotDataProvider<Instant>
{
    final private ReadWriteLock lock = new ReentrantReadWriteLock();

    /** To be set when samples change
     *  @see #testAndClearNewSamplesFlag()
     */
    final protected AtomicBoolean have_new_samples = new AtomicBoolean();

    /** Lock for writing */
    public void lockForWriting()
    {
        lock.writeLock().lock();
    }

    /** Un-lock after writing */
    public void unlockForWriting()
    {
        lock.writeLock().unlock();
        have_new_samples.set(true);
    }

    /** {@inheritDoc} */
    @Override
    public Lock getLock()
    {
        return lock.readLock();
    }

    /** {@inheritDoc} */
    @Override
    abstract public int size();

    /** {@inheritDoc} */
    @Override
    abstract public PlotSample get(int index);

    /** Test if samples changed since the last time
     *  <code>testAndClearNewSamplesFlag</code> was called.
     *  @return <code>true</code> if there were new samples
     */
    public boolean hasNewSamples()
    {
        return have_new_samples.get();
    }

    /** Test if samples changed since the last time this method was called.
     *  @return <code>true</code> if there were new samples
     */
    public boolean testAndClearNewSamplesFlag()
    {
        return have_new_samples.getAndSet(false);
    }

    /** @return Info text about PlotSamples for debugging */
    @SuppressWarnings("nls")
    @Override
    public String toString()
    {
        getLock().lock();
        try
        {
            final int n = size();
            final StringBuilder buf = new StringBuilder(n + " Plot Samples");
            if (n < 100)
                for (int i=0; i<n; ++i)
                    buf.append(String.format("\n%3d: ", i)).append(get(i));
            return buf.toString();
        }
        finally
        {
            getLock().unlock();
        }
    }
}

@@ -514,25 +514,169 @@
 ort 
-java.time.Instant
+static org.csstudio.javafx.rtplot.Activator.logger;%0A%0Aimport java.time.Instant;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.TimeoutException
 ;%0Aim
@@ -833,34 +833,75 @@
 til.
-concurrent.locks.Reentrant
+logging.Level;%0A%0Aimport org.csstudio.javafx.rtplot.data.Instrumented
 Read
@@ -911,17 +911,16 @@
 teLock;%0A
-%0A
 import o
@@ -1096,16 +1096,41 @@
 mir%0A */%0A
+@SuppressWarnings(%22nls%22)%0A
 abstract
@@ -1202,21 +1202,23 @@
     
-final private
+protected final
  Rea
@@ -1243,17 +1243,20 @@
 new 
-Reentrant
+Instrumented
 Read
@@ -1472,20 +1472,23 @@
  public 
-void
+boolean
  lockFor
@@ -1515,31 +1515,279 @@
     
-lock.writeLock().lock()
+try%0A        %7B%0A            if (! lock.writeLock().tryLock(10, TimeUnit.SECONDS))%0A                throw new TimeoutException();%0A        %7D%0A        catch (Exception ex)%0A        %7B%0A            logger.log(Level.WARNING, %22Cannot lock %22 + this, ex);%0A        %7D%0A        return false
 ;%0A  
@@ -2873,32 +2873,154 @@
 )%0A    %7B%0A        
+final StringBuilder buf = new StringBuilder();%0A        buf.append(%22Plot Samples, lock state: %22).append(lock);%0A        if (
 getLock().lock()
@@ -3013,23 +3013,36 @@
 tLock().
-l
+tryL
 ock()
-;
+)%0A        %7B
 %0A       
@@ -3034,32 +3034,36 @@
       %7B%0A        
+    
 try%0A        %7B%0A  
@@ -3050,34 +3050,42 @@
     try%0A        
+  
-%7B%0A
+  %7B%0A    
             fina
@@ -3118,64 +3118,49 @@
     
-final StringBuilder buf = new StringBuilder(n + %22 Plot S
+    buf.append(%22, %22).append(n).append(%22 s
 ampl
@@ -3165,16 +3165,20 @@
 ples%22);%0A
+    
         
@@ -3210,16 +3210,20 @@
         
+    
 for (int
@@ -3238,16 +3238,20 @@
 n; ++i)%0A
+    
         
@@ -3334,41 +3334,14 @@
     
-return buf.toString();
+%7D
 %0A    
-    %7D%0A
     
@@ -3352,34 +3352,42 @@
 finally%0A        
-%7B%0A
+    %7B%0A    
             getL
@@ -3406,22 +3406,67 @@
 ();%0A        
-%7D
+    %7D%0A        %7D%0A        return buf.toString();
 %0A    %7D%0A%7D%0A

Use instrumented read/write lock in PlotData