[concurrency-interest] Protecting sensitive resources

Mike Quilleash mike.quilleash at azuresolutions.com
Mon May 8 12:05:22 EDT 2006


Hi there,
 
I have a class that is responsible for delegating resources to other
classes.
 
Snapshot of the code below...
 
initalise() handles refreshing the internal state (other internal
variables which are not shown).
openSession() should create a new session and return it (unless
currently refreshing).
releaseSession() should return a session to the class and mark it as no
longer used.
 
 
The requirements for how this class should work is...
 
The class should keep track of current in-use session objects
(UsageSession) which must be threadsafe.
UsageSessions must be returned to the class when they are no longer
used.
The class may be reinitialised at any time in which case:
    It should not refresh until all Sessions have been returned.
    It should not allow any new sessions to be delegated out until
reinitialise is complete.
 
 
I'd appreciate any feedback or problems anyone sees with the
implementation below, I've stared at it for a while now and run through
the different possible scenarios of thread states etc but can't see any
problems.
 
Appreciate it.
 
Mike Quilleash.
 
 
 
 
 
    // set of currently open sessions
    private Set< UsageSession > openSessions;
 
    // locks and conditions protecting the open sessions list
    private Lock openSessionsLock = new ReentrantLock();
    private Condition openSessionsEmptyCondition =
openSessionsLock.newCondition();
    private Condition openSessionsNotRefreshingCondition =
openSessionsLock.newCondition();
    private volatile boolean refreshing = false;
 
    void initialise()
    {
        openSessionsLock.lock();
        try
        {
            // set refreshing flag
            refreshing = true;
 
            // wait for the open sessions list to be empty
            while( openSessions.size() > 0 )
            {
                openSessionsEmptyCondition.awaitUninterruptibly();
            }
 
            // clear out the open sessions - will already be empty
            openSessions = new HashSet< UsageSession >();
 
            // TODO: do initialisation here
 
            // clear refreshing flag
            refreshing = false;
 
            // signal all threads waiting on this condition
            openSessionsNotRefreshingCondition.signalAll();
        }
        finally
        {
            openSessionsLock.unlock();
        }
    }
 
    // open a usage session for use
    public UsageSession openSession()
    {
        // lock on the open sessions list
        openSessionsLock.lock();
        try
        {
            // if refreshing then wait for the refreshing condition
            while ( refreshing )
            {
                // wait on the not refreshing condition
 
openSessionsNotRefreshingCondition.awaitUninterruptibly();
            }
 
            UsageSession usageSession = new UsageSession( this );
 
            openSessions.add( usageSession );
 
            return usageSession;
        }
        finally
        {
            openSessionsLock.unlock();
        }
    }
 
    // call back made from the usage session when it is closed
    void releaseSession( UsageSession usageSession )
    {
        openSessionsLock.lock();
        try
        {
            if ( !openSessions.remove( usageSession ) )
                throw new IllegalArgumentException( "Attempted to
release unknown usage session" );
 
            // signal that the open sessions set is empty incase
something is waiting
            if ( openSessions.isEmpty() )
                openSessionsEmptyCondition.signalAll();
        }
        finally
        {
            openSessionsLock.unlock();
        }
    }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20060508/d5f1baaa/attachment.html


More information about the Concurrency-interest mailing list