Re: A recent change causes SCardCancel() to block?

Frank Morgner <[email protected]> Wed, 14 Jun 2017 16:05:51 +0200
Newsgroups gmane.comp.lib.muscle
Message-ID <CAO8bUynFM+ZGzv0pJ8yjdvr5-Uo79pXY3XzH=GP_Vy66aDD5YA@mail.gmail.com>
--===============0044487317393523431==
Content-Type: multipart/alternative; boundary="94eb2c149784c8b8220551ec0c7f"

--94eb2c149784c8b8220551ec0c7f
Content-Type: text/plain; charset="UTF-8"

I'm observing the same issue with pcsc-lite version 1.8.16 in OpenSC, where
we've activated a blocking SCardGetStatusChange recently. As a result,
OpenSC currently stalls Firefox when the browser is closed or the module is
unloaded. See also the OpenSC ticket
<https://github.com/OpenSC/OpenSC/issues/1065>.

Regards, Frank.

2017-06-14 11:43 GMT+02:00 Ran Benita <[email protected]>:

> Hello,
>
> I have noticed a change in behavior in one of the recent pcsclite
> releases. I am using pcsclite 1.8.21 and ccid 1.4.27 on ArchLinux.
>
> The program below calls a blocking SCardGetStatusChange, but before that
> spwans a thread which waits for a key press, then calls SCardCancel (on
> the same context). It is a port of the Rust program here:
> https://raw.githubusercontent.com/bluetech/pcsc-rust/
> 01bd4d80e366ef00f7006dabee45c8cb356d8566/pcsc/examples/cancel.rs
>
> Previously, the SCardCancel would return immediately and would cause
> SCardGetStatusChange to return SCARD_E_CANCELLED immediately.
>
> Now, SCardCancel blocks until SCardGetStatusChange times out, and only
> then returns SCARD_S_SUCCESS.
>
> Is this an intended change, or a regression? Or maybe I'm doing
> something wrong?
>
> Thanks,
> Ran
>
> // gcc -Wall -pthread $(pkg-config --libs --cflags libpcsclite) cancel.c
> -o cancel
> #include <stdio.h>
> #include <unistd.h>
> #include <assert.h>
> #include <pthread.h>
>
> #include <PCSC/winscard.h>
>
> static SCARDCONTEXT context;
>
> static void *canceler_thread(void *arg) {
>     LONG ret;
>
>     getchar();
>
>     printf("Calling SCardCancel...\n");
>     ret = SCardCancel(context);
>     assert(ret == SCARD_S_SUCCESS);
>     printf("SCardCancel returned SCARD_S_SUCCESS\n");
>
>     return NULL;
> }
>
> int main(void) {
>     LONG ret;
>
>     ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &context);
>     assert(ret == SCARD_S_SUCCESS);
>
>     // Spawn a thread which waits for a key-press then cancels the
> operation.
>     pthread_t thread;
>     ret = pthread_create(&thread, NULL, canceler_thread, NULL);
>
>     // Set up the blocking call, and wait for cancel or timeout.
>     printf("Entering blocking call; press Enter to cancel\n");
>     SCARD_READERSTATE reader_states[] = {
>         {
>             .szReader = "\\\\?PnP?\\Notification",
>             .pvUserData = NULL,
>             .dwCurrentState = SCARD_STATE_UNAWARE,
>             .dwEventState = SCARD_STATE_UNAWARE,
>         },
>     };
>
>     ret = SCardGetStatusChange(context, 5000, reader_states, 1);
>     switch (ret) {
>     case SCARD_S_SUCCESS:
>         printf("Blocking call exited normally\n");
>         break;
>
>     case SCARD_E_CANCELLED:
>         printf("Blocking call canceled\n");
>         break;
>
>     case SCARD_E_TIMEOUT:
>         printf("Blocking call timed out\n");
>         break;
>
>     default:
>         fprintf(stderr, "Failed to get status changes: %ld", ret);
>         break;
>     }
>
>     printf("Sleeping before existing main thread...\n");
>     sleep(5);
>
>     return 0;
> }
>
> _______________________________________________
> Pcsclite-muscle mailing list
> [email protected]
> http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
>

--94eb2c149784c8b8220551ec0c7f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I&#39;m observing the same issue with pcsc-lite versi=
on 1.8.16 in OpenSC, where we&#39;ve activated a blocking SCardGetStatusCha=
nge recently. As a result, OpenSC currently stalls Firefox when the browser=
 is closed or the module is unloaded. See also the <a href=3D"https://githu=
b.com/OpenSC/OpenSC/issues/1065">OpenSC ticket</a>.<br><br></div>Regards, F=
rank.<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">20=
17-06-14 11:43 GMT+02:00 Ran Benita <span dir=3D"ltr">&lt;<a href=3D"mailto=
:[email protected]" target=3D"_blank">[email protected]</a>&gt;</span>:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">Hello,<br>
<br>
I have noticed a change in behavior in one of the recent pcsclite<br>
releases. I am using pcsclite 1.8.21 and ccid 1.4.27 on ArchLinux.<br>
<br>
The program below calls a blocking SCardGetStatusChange, but before that<br=
>
spwans a thread which waits for a key press, then calls SCardCancel (on<br>
the same context). It is a port of the Rust program here:<br>
<a href=3D"https://raw.githubusercontent.com/bluetech/pcsc-rust/01bd4d80e36=
6ef00f7006dabee45c8cb356d8566/pcsc/examples/cancel.rs" rel=3D"noreferrer" t=
arget=3D"_blank">https://raw.githubusercontent.<wbr>com/bluetech/pcsc-rust/=
<wbr>01bd4d80e366ef00f7006dabee45c8<wbr>cb356d8566/pcsc/examples/<wbr>cance=
l.rs</a><br>
<br>
Previously, the SCardCancel would return immediately and would cause<br>
SCardGetStatusChange to return SCARD_E_CANCELLED immediately.<br>
<br>
Now, SCardCancel blocks until SCardGetStatusChange times out, and only<br>
then returns SCARD_S_SUCCESS.<br>
<br>
Is this an intended change, or a regression? Or maybe I&#39;m doing<br>
something wrong?<br>
<br>
Thanks,<br>
Ran<br>
<br>
// gcc -Wall -pthread $(pkg-config --libs --cflags libpcsclite) cancel.c -o=
 cancel<br>
#include &lt;stdio.h&gt;<br>
#include &lt;unistd.h&gt;<br>
#include &lt;assert.h&gt;<br>
#include &lt;pthread.h&gt;<br>
<br>
#include &lt;PCSC/winscard.h&gt;<br>
<br>
static SCARDCONTEXT context;<br>
<br>
static void *canceler_thread(void *arg) {<br>
=C2=A0 =C2=A0 LONG ret;<br>
<br>
=C2=A0 =C2=A0 getchar();<br>
<br>
=C2=A0 =C2=A0 printf(&quot;Calling SCardCancel...\n&quot;);<br>
=C2=A0 =C2=A0 ret =3D SCardCancel(context);<br>
=C2=A0 =C2=A0 assert(ret =3D=3D SCARD_S_SUCCESS);<br>
=C2=A0 =C2=A0 printf(&quot;SCardCancel returned SCARD_S_SUCCESS\n&quot;);<b=
r>
<br>
=C2=A0 =C2=A0 return NULL;<br>
}<br>
<br>
int main(void) {<br>
=C2=A0 =C2=A0 LONG ret;<br>
<br>
=C2=A0 =C2=A0 ret =3D SCardEstablishContext(SCARD_<wbr>SCOPE_USER, NULL, NU=
LL, &amp;context);<br>
=C2=A0 =C2=A0 assert(ret =3D=3D SCARD_S_SUCCESS);<br>
<br>
=C2=A0 =C2=A0 // Spawn a thread which waits for a key-press then cancels th=
e operation.<br>
=C2=A0 =C2=A0 pthread_t thread;<br>
=C2=A0 =C2=A0 ret =3D pthread_create(&amp;thread, NULL, canceler_thread, NU=
LL);<br>
<br>
=C2=A0 =C2=A0 // Set up the blocking call, and wait for cancel or timeout.<=
br>
=C2=A0 =C2=A0 printf(&quot;Entering blocking call; press Enter to cancel\n&=
quot;);<br>
=C2=A0 =C2=A0 SCARD_READERSTATE reader_states[] =3D {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .szReader =3D &quot;\\\\?PnP?\\No=
tification&quot;,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .pvUserData =3D NULL,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .dwCurrentState =3D SCARD_STATE_U=
NAWARE,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .dwEventState =3D SCARD_STATE_UNA=
WARE,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 },<br>
=C2=A0 =C2=A0 };<br>
<br>
=C2=A0 =C2=A0 ret =3D SCardGetStatusChange(context, 5000, reader_states, 1)=
;<br>
=C2=A0 =C2=A0 switch (ret) {<br>
=C2=A0 =C2=A0 case SCARD_S_SUCCESS:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf(&quot;Blocking call exited normally\n&qu=
ot;);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
<br>
=C2=A0 =C2=A0 case SCARD_E_CANCELLED:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf(&quot;Blocking call canceled\n&quot;);<b=
r>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
<br>
=C2=A0 =C2=A0 case SCARD_E_TIMEOUT:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf(&quot;Blocking call timed out\n&quot;);<=
br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
<br>
=C2=A0 =C2=A0 default:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &quot;Failed to get status chan=
ges: %ld&quot;, ret);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 printf(&quot;Sleeping before existing main thread...\n&quot;)=
;<br>
=C2=A0 =C2=A0 sleep(5);<br>
<br>
=C2=A0 =C2=A0 return 0;<br>
}<br>
<br>
______________________________<wbr>_________________<br>
Pcsclite-muscle mailing list<br>
<a href=3D"mailto:[email protected]">Pcsclite-muscle@=
lists.alioth.<wbr>debian.org</a><br>
<a href=3D"http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite=
-muscle" rel=3D"noreferrer" target=3D"_blank">http://lists.alioth.debian.<w=
br>org/cgi-bin/mailman/listinfo/<wbr>pcsclite-muscle</a><br>
</blockquote></div><br></div>

--94eb2c149784c8b8220551ec0c7f--


--===============0044487317393523431==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Pcsclite-muscle mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
--===============0044487317393523431==--