/*
 * JBoss, Home of Professional Open Source
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.optimistic;

import EDU.oswego.cs.dl.util.concurrent.Latch;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;

import javax.transaction.TransactionManager;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 */
public class OptimisticDeadlockTest extends AbstractOptimisticTestCase
{
    private static final int NUM_THREADS = 10;
    private static final int NUM_LOOPS = 10;
    private static final Fqn FQN = Fqn.fromString("/test");
    private static final Latch latch = new Latch();

    public OptimisticDeadlockTest(String name)
    {
        super(name);
    }

    public void testConcurrentReadsLocal() throws Exception
    {
        TreeCache cache = createCacheUnstarted();
        cache.setCacheMode("INVALIDATION_ASYNC");
        cache.startService();
        
        Processor[] processors = new Processor[NUM_THREADS];
        for (int i=0; i<NUM_THREADS; i++)
        {
            processors[i] = new Processor(cache, "Processor-" + i);
            processors[i].start();
        }

        cache.put(FQN, "key", "value");
        latch.release();

        for (int i=0; i<NUM_THREADS; i++)
            processors[i].join();


        for (int i=0; i<NUM_THREADS; i++)
        {
            assertEquals(0, processors[i].exceptions.size());
        }
    }

    public static class Processor extends Thread
    {
        private TreeCache cache;
        List exceptions = new ArrayList();

        public Processor(TreeCache cache, String name)
        {
            super(name);
            this.cache = cache;
        }

        public void run()
        {
            TransactionManager txman = cache.getTransactionManager();
            try
            {
                latch.acquire();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }

            for (int i=0; i<NUM_LOOPS; i++)
            {
                try
                {
                    txman.begin();
                    System.out.println("Processor " + getName() + " in loop " + i);
                    cache.get(FQN);
                    txman.commit();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    exceptions.add(e);
                }
            }
        }
    }

}
