← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1393026] [NEW] Synchronized decorator is not reentrant

 

Public bug reported:

It's impossible to call a synchronized method from the synchronized
method with the same lock name or use any kind of recursion. The
following test case hangs forever:

class TestLockUtils(base.BaseTestCase):
    
    def test_synchronized(self):
        
        @utils.synchronized('ab_test')
        def a():
            b()
            
        @utils.synchronized('ab_test')
        def b():
            pass
        
        @utils.synchronized('c_test')
        def c(n):
            if n == 0:
                return
            c(n -1)
          
        a()
        c(5)

The same logic works fine in Java:

public class JavaSynch {
    public synchronized void a() {
        b();
    }

    public synchronized void b() {
    }

    public synchronized void c(int n) {
        if (n == 0)
            return;
        c(n--);
    }

    public static void main(String[] args) {
        JavaSynch js = new JavaSynch();
        js.a();
    }
}

Synchronized decorator from neutron.openstack.common.lockutils uses
semaphore which can't track the current owner of the lock. It would be
good to use RLock, but I understand that eventless greenthreads  must be
taken into account.

Currently this behavior stop fixing us
https://bugs.launchpad.net/neutron/+bug/1197176 because delete_network
should call delete_subnet, but these methods are synchronized using the
same lock in BigSwithc plugin.

** Affects: neutron
     Importance: Undecided
     Assignee: Alexey Miroshkin (amirosh)
         Status: New

** Changed in: neutron
     Assignee: (unassigned) => Alexey Miroshkin (amirosh)

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to neutron.
https://bugs.launchpad.net/bugs/1393026

Title:
  Synchronized decorator is not reentrant

Status in OpenStack Neutron (virtual network service):
  New

Bug description:
  It's impossible to call a synchronized method from the synchronized
  method with the same lock name or use any kind of recursion. The
  following test case hangs forever:

  class TestLockUtils(base.BaseTestCase):
      
      def test_synchronized(self):
          
          @utils.synchronized('ab_test')
          def a():
              b()
              
          @utils.synchronized('ab_test')
          def b():
              pass
          
          @utils.synchronized('c_test')
          def c(n):
              if n == 0:
                  return
              c(n -1)
            
          a()
          c(5)

  The same logic works fine in Java:

  public class JavaSynch {
      public synchronized void a() {
          b();
      }

      public synchronized void b() {
      }

      public synchronized void c(int n) {
          if (n == 0)
              return;
          c(n--);
      }

      public static void main(String[] args) {
          JavaSynch js = new JavaSynch();
          js.a();
      }
  }

  Synchronized decorator from neutron.openstack.common.lockutils uses
  semaphore which can't track the current owner of the lock. It would be
  good to use RLock, but I understand that eventless greenthreads  must
  be taken into account.

  Currently this behavior stop fixing us
  https://bugs.launchpad.net/neutron/+bug/1197176 because delete_network
  should call delete_subnet, but these methods are synchronized using
  the same lock in BigSwithc plugin.

To manage notifications about this bug go to:
https://bugs.launchpad.net/neutron/+bug/1393026/+subscriptions


Follow ups

References