1 Reply Latest reply on Feb 25, 2007 3:33 AM by Tim Fox

    Why failoverValve has the ThreadLocal routine

    Clebert Suconic Master

      Basically this is the scenario... You have several threads trying to acquire the writeLock simultaneously... Different from a Tomcat Valve where from what I remember when I read the code, then don't have such requirement.

      You have several threads... each one with a readLock...

      then all of these threads will try to acquire a writeLock...

      Any thread will be able to assume the writeLock... as there are other threads with readLocks.

      so... before acquiring the writeLock, I would need to release the readLock...

      But... as the Valve is Reentrant.. I needed to store the number of reentrances before releasing readLocks executed before.


      The only solution to avoid the ThreadLocal would be to avoid reentrance on the Valve and aways release one readlock.. but I don't think that's completely possible. But if anyone can find a way to have this following test work (without releasing a readLock), we can apply the fix to the Valve:


      public void testOnReadlocks() throws Exception
       {
       int THREAD_COUNT = 10;
       final ReadWriteLock readWriteLock = new WriterPreferenceReadWriteLock();
       final Object sync = new Object();
      
       Thread threads[] = new Thread[THREAD_COUNT];
      
       for (int i = 0; i < THREAD_COUNT; i++)
       {
       threads = new Thread()
       {
       public void run()
       {
       try
       {
       synchronized (sync)
       {
       sync.wait();
       }
       readWriteLock.readLock().acquire();
       readWriteLock.writeLock().acquire();
       }
       catch (Exception e)
       {
       e.printStackTrace();
       }
       }
       };
       threads.start();
       }
      
       Thread.sleep(2000);
      
       synchronized (sync)
       {
       sync.notify();
       }
      
       for (int i=0;i<threads.length;i++)
       {
       threads.join();
       }
       }
      


      This test would hang forever

        • 1. Re: Why failoverValve has the ThreadLocal routine
          Tim Fox Master

          I've just woken up and this is off the top of my head, untried, but how about something like this:

          class Valve
          {
           private int count;
           private boolean locked;
          
           public synchronized void enter()
           {
           while (locked)
           {
           wait();
           }
           count++;
           }
          
           public synchronized void exit()
           {
           count--;
          
           notifyAll();
           }
          
           public synchronized void lock()
           {
           if (locked) return;
          
           locked = true;
          
           while (count > 0)
           {
           wait();
           }
          
           }
          
           public synchronized void unlock()
           {
           if (!locked) return;
          
           locked = false;
          
           notifyAll();
           }
          }