[JAVA-616] Semaphore released more times than acquired (java.lang.Error thrown on java 7) Created: 02/Aug/12  Updated: 29/Aug/12  Resolved: 07/Aug/12

Status: Closed
Project: Java Driver
Component/s: Connection Management
Affects Version/s: 2.7.3
Fix Version/s: 2.9.0

Type: Bug Priority: Major - P3
Reporter: gross Assignee: Jeffrey Yemin
Resolution: Done Votes: 0
Labels: crash, driver
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

linux 2.6, 3.4
openjdk7, oracle jdk7 (u2, u4, u5)



 Description   

It seems like _waiting semaphore release more times than acquired.

Java 6 was tolerant to releasing a lot of permits (so it just overflows without any significant promblems). It may hold some threads in temporal starvation (because semapthore will have negative number of permits). But with such error after some time it will return to normal state.

But Java 7 will throw java.lang.Error in such case.

There's stack trace:

java.lang.Error: Maximum permit count exceeded
  at java.util.concurrent.Semaphore$Sync.tryReleaseShared(Semaphore.java:197) [rt.jar:1.7.0_04]
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1340) [rt.jar:1.7.0_04]
  at java.util.concurrent.Semaphore.release(Semaphore.java:431) [rt.jar:1.7.0_04]
  at com.mongodb.util.SimplePool.done(SimplePool.java:129) [mongo-java-driver-2.7.3.jar:]
  at com.mongodb.util.SimplePool.done(SimplePool.java:103) [mongo-java-driver-2.7.3.jar:]



 Comments   
Comment by Jeffrey Yemin [ 29/Aug/12 ]

Closing as part of 2.9.0 release process.

Comment by auto [ 07/Aug/12 ]

Author:

{u'date': u'2012-08-07T09:36:06-07:00', u'email': u'jeff.yemin@10gen.com', u'name': u'Jeff Yemin'}

Message: JAVA-616: To fix issue with the Semaphore overflowing, made SimplePool class a lot... simpler.
1. Removed support for unlimited pool size. Now there is a single maximum size of the pool, representing the total number of potentially available and in-use members
2. Semaphore now has one permit for each pool member that are potentially available (either in available list or could be created).
3. Synchronized on this. Only enter synchronization block in get method if a permit has been acquired
4. Keeping track of list of available members (_avail) and set of checked out members (_out).
Get method removes from _avail or creates new member, and adds to _out. Done method removes from _out and adds to _avail.
5. Removed debug and track leaks support
6. Updated JMX monitoring interface to reflect the new structure.
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/ade11ca176b1bb729f5f65a673e507f2217bbbf4

Comment by Jeffrey Yemin [ 03/Aug/12 ]

Thanks for reporting this. Can you work around this for now by restarting your application more often than that?

Comment by gross [ 03/Aug/12 ]

Yes, about 2 months.

Comment by Jeffrey Yemin [ 03/Aug/12 ]

Yeah, I see the difference in the code for Java 6 and Java 7. This will happen after Integer.MAX_VALUE uncontended releases to the connection pool. I assume this happened after running your application for quite a while?

Generated at Thu Feb 08 08:52:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.