[Pcsclite-muscle] A recent change causes SCardCancel() to block?
Ran Benita
ran234
Wed Jun 14 02:43:46 PDT 2017
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;
}
More information about the pcsclite-muscle
mailing list