I was trying to log connections as they move in and out of the pool so my team can diagnose inefficient connection usage. I added a ConnectionCustomizer that logs the number of busy, idle & orphaned connections in each datasource whenever a connection is acquired or destroyed. Everything seemed fine until we noticed a deadlock on shutdown.
It turns out I have a deadlock due to lock ordering between C3P0Registry and PoolBackedDataSource. I call C3P0Registry to get the list of DataSources to log. It locks the DataSources as it puts them in a set to return (the hashcode method locks). On a shutdown, the locks are called in opposite order. The pool is closed, and then it calls C3P0Registry to mark itself as closed.
Is there a better way for me to do this? Does c3p0 declare it's intended lock ordering somewhere? The only rock-solid solution I can think of is to lock on C3P0Registry before shutting down the datasource.