node-pcsclite icon indicating copy to clipboard operation
node-pcsclite copied to clipboard

How to shut down an application cleanly?

Open martinpaljak opened this issue 7 years ago • 3 comments

I am a bit confused about cleanly closing the runtime after I am done with the reader I am interested in.

There is reader.disconnect() which is a wrapper around SCardDisconnect(), thus I obviously call it.

Then there is reader.close() which is intended to call SCardCancel() (for this specific reader?). I call it and get no errors.

Then there is pcsc.close() which is intended to also call SCardCancel() (for PnP reader tracking?). I call it and get an error event on pcsc: SCardGetStatusChange error: Command cancelled.(0x80100002). And the node process does not exit after this call. AFAIU SCardGetStatusChange should never emit an error if it is cancelled (I suspect this is a bug)

Two questions:

  • How do I properly clean up the runtime, without calling process.exit()?
  • Why are there two status checkers? AFAIU one call for SCardGetStatusChange should be sufficient, also for getting events for the pnp pseudo-reader as well as any connected readers, to be able to emit reade events (thus a pcsc.close() should be sufficient, and should result in normal exit of nodejs runtime?)

martinpaljak avatar Apr 25 '17 07:04 martinpaljak

@martinpaljak thanks for the detailed report.

WRT pcsc.close(), reader.close(), it's not just about calling SCardCancel() but also cleaning up the threads where SCardGetStatusChange() run. If the program doesn't exit it's probably due to a deadlock. Can you post code that reproduces the error? (platform/reader/ etc)

Why are there two status checkers? AFAIU one call for SCardGetStatusChange should be sufficient, also for getting events for the pnp pseudo-reader as well as any connected readers, to be able to emit reade events (thus a pcsc.close() should be sufficient, and should result in normal exit of nodejs runtime?)

You're right. This could be done with only one SCardGetStatusChange(). It's been on my radar for a while but haven't had time yet. Would you be up for it :) ?

santigimeno avatar Apr 25 '17 08:04 santigimeno

I tried to read and fix some, but got lost in the code and how threads are handled with libuv (?) and ... I might come back to this at some later time or with #71 , right now process.exit() is OK for me.

martinpaljak avatar Apr 25 '17 08:04 martinpaljak

@martinpaljak This can easily be avoided if you simply set an error listener on the main pcsc object. I ran into the same problem (SCardCancel error notification on pcsc.close(), which is indeed unexpected), and I noticed that this output is done from the node EventEmitter code, which treats "error" events as a special case and prints the message when there is no listener.

So, as an easy fix, just set an empty listener:

pcsc.on('error', function(err) {
});

Or, if you want to handle the errors from the listener but only ignore the SCardCancel case, set a flag before doing pcsc.close() and, in your listener, ignore any error that may arise after set flag is set.

dimdimdimdim avatar Jan 30 '19 14:01 dimdimdimdim