[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ms-smartcardsdk
Subject:    Re: How would SCardReleaseContext hang?
From:       Dan Griffin <dangriff () WINDOWS ! MICROSOFT ! COM>
Date:       2003-08-08 19:57:37
[Download RAW message or body]

Phillip, we typically recommend that the polling thread release its own
context handle before it terminates.  One reason is that, in your model,
the main thread will in many cases end up closing (or at least trying to
close) the context handle before the smartcard service has had a chance
to respond to the Cancel.  

Give that a shot and we'll go from there.

Dan Griffin [MS]

-----Original Message-----
From: SmartCardSDK [mailto:SmartCardSDK@DISCUSS.MICROSOFT.COM] On Behalf
Of Phillip Fanous
Sent: Friday, August 08, 2003 12:48 PM
To: SmartCardSDK@DISCUSS.MICROSOFT.COM
Subject: Re: How would SCardReleaseContext hang?


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.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic