Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 339164

Summary: File level locking doesn't 'lock' the file between multiple threads in the same VM (Java 1.5)
Product: [Eclipse Project] Equinox Reporter: Ian Bull <irbull>
Component: p2Assignee: Ian Bull <irbull>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: david_williams, tjwatson
Version: unspecified   
Target Milestone: 3.7 M7   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Patch v1
none
mylyn/context/zip
none
Patch v2
none
mylyn/context/zip none

Description Ian Bull CLA 2011-03-08 00:52:06 EST
On a 1.5 VM, the file level locking doesn't appear to 'lock' a location between threads in the same process. That is, if one thread calls lock(), and another thread calls isLocked(), on a 1.5 VM, the call to isLocked() will return *false*, whereas on a 1.6 VM the call to isLocked() will return *true*.

This code snippet demonstrates the problem:

public Object start(IApplicationContext context) throws Exception {  
  Thread t = new Thread(new Runnable() {		
    public void run() {
	  try {
		  lockLocation = getLockLocation(new URI("file:///home/irbull/tmp/locktest"), 1);
		  lockLocation.lock();
	  } catch (IllegalStateException e) {
  		  e.printStackTrace();
  	  } catch (IOException e) {
		  e.printStackTrace();
	  } catch (URISyntaxException e) {
		  e.printStackTrace();
	  }
  }
  });
  t.start();
  t.join();
  System.out.println(getLockLocation(new URI("file:///home/irbull/tmp/locktest"),1).isLocked());
}

private static Location getLockLocation(URI baseLocation, int locationNumber)
		throws IllegalStateException, IOException {
		Location anyLoc = (Location)  Activator.getService(Location.class.getName());
		URI locationURI = URIUtil.append(baseLocation, "" + locationNumber);
		Location location = anyLoc.createLocation(null, URIUtil.toURL(locationURI), false); //$NON-NLS-1$
		location.set(URIUtil.toURL(locationURI),false);
	return location;
}

I didn't see either behaviour specified in the Location class, but maybe I missed it.  This doesn't represent a regression as this never worked before.  However, we should fix this for 3.7.
Comment 1 Thomas Watson CLA 2011-03-08 08:50:43 EST
Within the same VM you should really use the same Location object.  That is why we register the locations as a service, so that all clients within the same framework are using the same instance.  The Location object contains state to keep track if the location has been locked within the same process.
Comment 2 Ian Bull CLA 2011-03-29 12:30:39 EDT
Created attachment 192112 [details]
Patch v1

This patch uses a static map to manage the Lock locations.  We need to consider what to do with these locations on bundle.stop().
Comment 3 Ian Bull CLA 2011-03-29 12:30:42 EDT
Created attachment 192113 [details]
mylyn/context/zip
Comment 4 Ian Bull CLA 2011-03-29 13:55:16 EDT
Created attachment 192115 [details]
Patch v2

I've moved the cache to the activator so we can clean it up on stop() / start().
Comment 5 Ian Bull CLA 2011-03-29 13:55:19 EDT
Created attachment 192116 [details]
mylyn/context/zip
Comment 6 Ian Bull CLA 2011-03-29 14:05:39 EDT
I've added some comments and released patch v2 to head.  I've also enabled some more test cases that demonstrate this behaviour.