OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Re: How would SCardReleaseContext hang?

From: Phillip Fanous (phill.fanousLITRONIC.COM)
Date: Fri Aug 08 2003 - 14:47:59 CDT


The main code is pretty involved, but I'll try to generalize. The code
consists of a thread (main thread) that spawns another thread to perform
the polling over the readers. The polling thread responds to insertions and
removals of smart cards. The main thread performs the SCardTransmits.

Here's the steps for initialization:

SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hMainContext);

SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hPollingContext);

* Polling thread is created with the code below

/////// BEGIN Polling Thread //////////
SCardListReaders(...) is called to retrieve the multi-string of reader
names and an SCARD_READERSTATE array is constructed

for (;;)
{
        status = SCardGetStatusChange(hPollingContext,
                                      INFINITE,
                                      reader_states,
                                      num_readers);
        if (status == SCARD_E_CANCELLED)
            break;

        for (i = 0; i < num_readers; i++)
        {
            // card removed
            if ( !(reader_states[i].dwCurrentState & SCARD_STATE_EMPTY) &&
                  (reader_states[i].dwEventState & SCARD_STATE_EMPTY) )
            {
               ....
            }

            // card inserted
            if ( !(reader_states[i].dwCurrentState & SCARD_STATE_PRESENT) &&
                  (reader_states[i].dwEventState & SCARD_STATE_PRESENT) )
            {
               ....
            }

            // update current state
            reader_states[i].dwCurrentState = reader_states[i].dwEventState;
        }
}
/////// END Polling Thread //////////

Here's the steps for the destruction:

Main thread:

SCardCancel(hPollingContext);
SCardReleaseContext(hPollingContext); // Here's where it hangs
SCardReleaseContext(hMainContext);

In between the construction and destruction process:

* Upon a card insertion detected by the polling thread, SCardConnect
(hMainContext, ...) is called to connect to the card.
* Upon card removal, SCardDisconnect(hMainContext, ..., SCARD_LEAVE_CARD)
is called
 * Between insertion and removal, a series of SCardTransmits(...) is
made.

BTW, SCardDisconnect(..., SCARD_LEAVE_CARD) is explicitly called to ensure
that the default of a disconnect with a reset is not performed.

When running a single process, no problems show up. When running 2
processes of the code listed above... the call to SCardCancel(..) ends the
waiting for the SCardGetStatusChange(...) call in the polling thread
allowing the thread to terminate appropriately. The succeeding call to
SCardReleaseContext(hPollingContext) causes the hang. It's hanging in the
same place in both processes.