public void registerDeferredService ( BundleContext bundleContext , Class < ? > providedService , Dictionary dict ) { Object obj = serviceReg . get ( ) ; if ( obj instanceof ServiceRegistration < ? > ) { // already registered - nothing to do here return ; } if ( obj instanceof CountDownLatch ) { // another thread is in the process of (de)registering - wait for it to finish try { ( ( CountDownLatch ) obj ) . await ( ) ; if ( serviceReg . get ( ) instanceof ServiceRegistration < ? > ) { // Another thread has successfully registered to return out (so we don't go // into recursive loop). return ; } } catch ( InterruptedException swallowed ) { if ( tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "Count down interrrupted" , swallowed ) ; } } } else { // This is probably the first thread to register. // Claim the right to register by setting a latch for other threads to wait on. CountDownLatch latch = new CountDownLatch ( 1 ) ; if ( serviceReg . compareAndSet ( null , latch ) ) { // This thread won the right to register the service try { serviceReg . set ( bundleContext . registerService ( providedService . getName ( ) , this , dict ) ) ; // successfully registered - nothing more to do return ; } finally { // if the serviceReg was not updated for any reason, we need to set it back to null serviceReg . compareAndSet ( latch , null ) ; // in any case we need to allow any blocked threads to proceed latch . countDown ( ) ; } } } // If we get to here we have not successfully registered // nor seen another thread successfully register, so just recurse. registerDeferredService ( bundleContext , providedService , dict ) ; }
Register information available after class loader is created for use by RAR bundle