package railo.runtime.db; import java.sql.SQLException; import railo.commons.lang.SystemOut; import railo.runtime.PageContext; class DCStack { private Item item; DCStack() { } public synchronized void add(DatasourceConnection dc){ // make sure the connection is not already in stack, this can happen when the conn is released twice Item test = item; while(test!=null){ if(test.dc==dc) { SystemOut.print("a datasource connection was released twice!"); return; } test=test.prev; } item=new Item(item,dc); } public synchronized DatasourceConnection get(PageContext pc){ if(item==null) return null; DatasourceConnection rtn = item.dc; item=item.prev; try { if(!rtn.getConnection().isClosed()){ return rtn; } return get(pc); } catch (SQLException e) {} return null; } public synchronized boolean isEmpty(){ return item==null; } public synchronized int size(){ int count=0; Item i = item; while(i!=null){ count++; i=i.prev; } return count; } public int openConnections(){ int count=0; Item i = item; while(i!=null){ try { if(!i.dc.getConnection().isClosed())count++; } catch (SQLException e) {} i=i.prev; } return count; } class Item { private DatasourceConnection dc; private Item prev; private int count=1; public Item(Item item,DatasourceConnection dc) { this.prev=item; this.dc=dc; if(prev!=null)count=prev.count+1; } public String toString(){ return "("+prev+")<-"+count; } } public synchronized void clear() { try { clear(item,null); } catch (SQLException e) {} } private void clear(Item current,Item next) throws SQLException { if(current==null) return; if((current.dc.isTimeout() || current.dc.getConnection().isClosed())) { if(!current.dc.getConnection().isClosed()){ try { current.dc.close(); } catch (SQLException e) {} } if(next==null)item=current.prev; else { next.prev=current.prev; } clear(current.prev,next); } else clear(current.prev,current); } }