src: migrate pthreads to uv_threads
- So it can be compatible in every platform supported by libuv. - Use attached threads instead of detached. - Remove all CardReader 'status' listeners before emitting the 'end' event.
This commit is contained in:
@@ -59,6 +59,11 @@ module.exports = function() {
|
|||||||
r.state = state;
|
r.state = state;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
r.on('_end', function() {
|
||||||
|
r.removeAllListeners('status');
|
||||||
|
r.emit('end');
|
||||||
|
});
|
||||||
|
|
||||||
p.emit('reader', r);
|
p.emit('reader', r);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -102,7 +107,6 @@ CardReader.prototype.disconnect = function(disposition, cb) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CardReader.prototype.transmit = function(data, res_len, protocol, cb) {
|
CardReader.prototype.transmit = function(data, res_len, protocol, cb) {
|
||||||
|
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
return cb(new Error("Card Reader not connected"));
|
return cb(new Error("Card Reader not connected"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <v8.h>
|
|
||||||
|
|
||||||
#include "pcsclite.h"
|
#include "pcsclite.h"
|
||||||
#include "cardreader.h"
|
#include "cardreader.h"
|
||||||
|
|
||||||
|
|||||||
@@ -61,21 +61,22 @@ void CardReader::init(Handle<Object> target) {
|
|||||||
|
|
||||||
CardReader::CardReader(const std::string &reader_name): m_card_context(0),
|
CardReader::CardReader(const std::string &reader_name): m_card_context(0),
|
||||||
m_card_handle(0),
|
m_card_handle(0),
|
||||||
m_name(reader_name) {
|
m_name(reader_name),
|
||||||
pthread_mutex_init(&m_mutex, NULL);
|
m_state(0) {
|
||||||
|
assert(uv_mutex_init(&m_mutex) == 0);
|
||||||
|
assert(uv_cond_init(&m_cond) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardReader::~CardReader() {
|
CardReader::~CardReader() {
|
||||||
|
SCardCancel(m_card_context);
|
||||||
|
int ret = uv_thread_join(&m_status_thread);
|
||||||
|
assert(ret == 0);
|
||||||
|
|
||||||
if (m_card_context) {
|
if (m_card_context) {
|
||||||
SCardReleaseContext(m_card_context);
|
SCardReleaseContext(m_card_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_status_card_context) {
|
uv_mutex_destroy(&m_mutex);
|
||||||
SCardCancel(m_status_card_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&m_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NAN_METHOD(CardReader::New) {
|
NAN_METHOD(CardReader::New) {
|
||||||
@@ -104,8 +105,8 @@ NAN_METHOD(CardReader::GetStatus) {
|
|||||||
async_baton->reader = obj;
|
async_baton->reader = obj;
|
||||||
|
|
||||||
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
||||||
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
int ret = uv_thread_create(&obj->m_status_thread, HandlerFunction, async_baton);
|
||||||
pthread_detach(obj->m_status_thread);
|
assert(ret == 0);
|
||||||
|
|
||||||
NanReturnUndefined();
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
@@ -298,10 +299,23 @@ NAN_METHOD(CardReader::Close) {
|
|||||||
|
|
||||||
NanScope();
|
NanScope();
|
||||||
|
|
||||||
|
LONG result = SCARD_S_SUCCESS;
|
||||||
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
CardReader* obj = ObjectWrap::Unwrap<CardReader>(args.This());
|
||||||
|
|
||||||
LONG result = SCardCancel(obj->m_status_card_context);
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
obj->m_status_card_context = 0;
|
if (obj->m_state == 0) {
|
||||||
|
obj->m_state = 1;
|
||||||
|
do {
|
||||||
|
result = SCardCancel(obj->m_status_card_context);
|
||||||
|
} while (uv_cond_timedwait(&obj->m_cond, &obj->m_mutex, 10000000) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
uv_mutex_destroy(&obj->m_mutex);
|
||||||
|
uv_cond_destroy(&obj->m_cond);
|
||||||
|
|
||||||
|
assert(uv_thread_join(&obj->m_status_thread) == 0);
|
||||||
|
obj->m_status_thread = 0;
|
||||||
|
|
||||||
NanReturnValue(NanNew<Number>(result));
|
NanReturnValue(NanNew<Number>(result));
|
||||||
}
|
}
|
||||||
@@ -318,7 +332,7 @@ void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
|
|
||||||
/* Emit end event */
|
/* Emit end event */
|
||||||
Handle<Value> argv[1] = {
|
Handle<Value> argv[1] = {
|
||||||
NanNew("end"), // event name
|
NanNew("_end"), // event name
|
||||||
};
|
};
|
||||||
|
|
||||||
NanMakeCallback(NanObjectWrapHandle(async_baton->reader), "emit", 1, argv);
|
NanMakeCallback(NanObjectWrapHandle(async_baton->reader), "emit", 1, argv);
|
||||||
@@ -343,27 +357,39 @@ void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* CardReader::HandlerFunction(void* arg) {
|
void CardReader::HandlerFunction(void* arg) {
|
||||||
|
|
||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(arg);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(arg);
|
||||||
CardReader* reader = async_baton->reader;
|
CardReader* reader = async_baton->reader;
|
||||||
async_baton->async_result = new AsyncResult();
|
async_baton->async_result = new AsyncResult();
|
||||||
async_baton->async_result->do_exit = false;
|
async_baton->async_result->do_exit = false;
|
||||||
|
|
||||||
/* Lock mutex */
|
|
||||||
pthread_mutex_lock(&reader->m_mutex);
|
|
||||||
LONG result = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &reader->m_status_card_context);
|
LONG result = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &reader->m_status_card_context);
|
||||||
/* Unlock the mutex */
|
|
||||||
pthread_mutex_unlock(&reader->m_mutex);
|
|
||||||
|
|
||||||
SCARD_READERSTATE card_reader_state = SCARD_READERSTATE();
|
SCARD_READERSTATE card_reader_state = SCARD_READERSTATE();
|
||||||
card_reader_state.szReader = reader->m_name.c_str();
|
card_reader_state.szReader = reader->m_name.c_str();
|
||||||
card_reader_state.dwCurrentState = SCARD_STATE_UNAWARE;
|
card_reader_state.dwCurrentState = SCARD_STATE_UNAWARE;
|
||||||
|
|
||||||
while(result == SCARD_S_SUCCESS &&
|
bool keep_watching(result == SCARD_S_SUCCESS);
|
||||||
!((card_reader_state.dwCurrentState & SCARD_STATE_UNKNOWN) ||
|
while (keep_watching) {
|
||||||
(card_reader_state.dwCurrentState & SCARD_STATE_UNAVAILABLE))) {
|
|
||||||
result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1);
|
result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1);
|
||||||
|
keep_watching = ((result == SCARD_S_SUCCESS) &&
|
||||||
|
(!reader->m_state) &&
|
||||||
|
(!((card_reader_state.dwCurrentState & SCARD_STATE_UNKNOWN) ||
|
||||||
|
(card_reader_state.dwCurrentState & SCARD_STATE_UNAVAILABLE))));
|
||||||
|
|
||||||
|
uv_mutex_lock(&reader->m_mutex);
|
||||||
|
if (reader->m_state == 1) {
|
||||||
|
uv_cond_signal(&reader->m_cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!keep_watching) {
|
||||||
|
reader->m_state = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&reader->m_mutex);
|
||||||
|
|
||||||
async_baton->async_result->result = result;
|
async_baton->async_result->result = result;
|
||||||
async_baton->async_result->status = card_reader_state.dwEventState;
|
async_baton->async_result->status = card_reader_state.dwEventState;
|
||||||
memcpy(async_baton->async_result->atr, card_reader_state.rgbAtr, card_reader_state.cbAtr);
|
memcpy(async_baton->async_result->atr, card_reader_state.rgbAtr, card_reader_state.cbAtr);
|
||||||
@@ -374,8 +400,6 @@ void* CardReader::HandlerFunction(void* arg) {
|
|||||||
|
|
||||||
async_baton->async_result->do_exit = true;
|
async_baton->async_result->do_exit = true;
|
||||||
uv_async_send(&async_baton->async);
|
uv_async_send(&async_baton->async);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::DoConnect(uv_work_t* req) {
|
void CardReader::DoConnect(uv_work_t* req) {
|
||||||
@@ -388,7 +412,7 @@ void CardReader::DoConnect(uv_work_t* req) {
|
|||||||
CardReader* obj = baton->reader;
|
CardReader* obj = baton->reader;
|
||||||
|
|
||||||
/* Lock mutex */
|
/* Lock mutex */
|
||||||
pthread_mutex_lock(&obj->m_mutex);
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
/* Is context established */
|
/* Is context established */
|
||||||
if (!obj->m_card_context) {
|
if (!obj->m_card_context) {
|
||||||
result = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &obj->m_card_context);
|
result = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &obj->m_card_context);
|
||||||
@@ -405,7 +429,7 @@ void CardReader::DoConnect(uv_work_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
pthread_mutex_unlock(&obj->m_mutex);
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
|
||||||
ConnectResult *cr = new ConnectResult();
|
ConnectResult *cr = new ConnectResult();
|
||||||
cr->result = result;
|
cr->result = result;
|
||||||
@@ -456,7 +480,7 @@ void CardReader::DoDisconnect(uv_work_t* req) {
|
|||||||
CardReader* obj = baton->reader;
|
CardReader* obj = baton->reader;
|
||||||
|
|
||||||
/* Lock mutex */
|
/* Lock mutex */
|
||||||
pthread_mutex_lock(&obj->m_mutex);
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
/* Connect */
|
/* Connect */
|
||||||
if (obj->m_card_handle) {
|
if (obj->m_card_handle) {
|
||||||
result = SCardDisconnect(obj->m_card_handle, *disposition);
|
result = SCardDisconnect(obj->m_card_handle, *disposition);
|
||||||
@@ -466,7 +490,7 @@ void CardReader::DoDisconnect(uv_work_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
pthread_mutex_unlock(&obj->m_mutex);
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
|
||||||
baton->result = reinterpret_cast<void*>(new LONG(result));
|
baton->result = reinterpret_cast<void*>(new LONG(result));
|
||||||
}
|
}
|
||||||
@@ -515,7 +539,7 @@ void CardReader::DoTransmit(uv_work_t* req) {
|
|||||||
LONG result = SCARD_E_INVALID_HANDLE;
|
LONG result = SCARD_E_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Lock mutex */
|
/* Lock mutex */
|
||||||
pthread_mutex_lock(&obj->m_mutex);
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
/* Connected? */
|
/* Connected? */
|
||||||
if (obj->m_card_handle) {
|
if (obj->m_card_handle) {
|
||||||
SCARD_IO_REQUEST send_pci = { ti->card_protocol, sizeof(SCARD_IO_REQUEST) };
|
SCARD_IO_REQUEST send_pci = { ti->card_protocol, sizeof(SCARD_IO_REQUEST) };
|
||||||
@@ -524,7 +548,7 @@ void CardReader::DoTransmit(uv_work_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
pthread_mutex_unlock(&obj->m_mutex);
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
|
||||||
tr->result = result;
|
tr->result = result;
|
||||||
|
|
||||||
@@ -575,7 +599,7 @@ void CardReader::DoControl(uv_work_t* req) {
|
|||||||
LONG result = SCARD_E_INVALID_HANDLE;
|
LONG result = SCARD_E_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Lock mutex */
|
/* Lock mutex */
|
||||||
pthread_mutex_lock(&obj->m_mutex);
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
/* Connected? */
|
/* Connected? */
|
||||||
if (obj->m_card_handle) {
|
if (obj->m_card_handle) {
|
||||||
result = SCardControl(obj->m_card_handle,
|
result = SCardControl(obj->m_card_handle,
|
||||||
@@ -588,7 +612,7 @@ void CardReader::DoControl(uv_work_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
pthread_mutex_unlock(&obj->m_mutex);
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
|
||||||
cr->result = result;
|
cr->result = result;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <nan.h>
|
#include <nan.h>
|
||||||
#include <node_version.h>
|
#include <node_version.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <pthread.h>
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <PCSC/winscard.h>
|
#include <PCSC/winscard.h>
|
||||||
#include <PCSC/wintypes.h>
|
#include <PCSC/wintypes.h>
|
||||||
@@ -100,7 +99,7 @@ class CardReader: public node::ObjectWrap {
|
|||||||
static NAN_METHOD(Close);
|
static NAN_METHOD(Close);
|
||||||
|
|
||||||
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
||||||
static void* HandlerFunction(void* arg);
|
static void HandlerFunction(void* arg);
|
||||||
static void DoConnect(uv_work_t* req);
|
static void DoConnect(uv_work_t* req);
|
||||||
static void DoDisconnect(uv_work_t* req);
|
static void DoDisconnect(uv_work_t* req);
|
||||||
static void DoTransmit(uv_work_t* req);
|
static void DoTransmit(uv_work_t* req);
|
||||||
@@ -120,8 +119,10 @@ class CardReader: public node::ObjectWrap {
|
|||||||
SCARDCONTEXT m_status_card_context;
|
SCARDCONTEXT m_status_card_context;
|
||||||
SCARDHANDLE m_card_handle;
|
SCARDHANDLE m_card_handle;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
pthread_t m_status_thread;
|
uv_thread_t m_status_thread;
|
||||||
pthread_mutex_t m_mutex;
|
uv_mutex_t m_mutex;
|
||||||
|
uv_cond_t m_cond;
|
||||||
|
int m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CARDREADER_H */
|
#endif /* CARDREADER_H */
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ void PCSCLite::init(Handle<Object> target) {
|
|||||||
PCSCLite::PCSCLite(): m_card_context(0),
|
PCSCLite::PCSCLite(): m_card_context(0),
|
||||||
m_card_reader_state(),
|
m_card_reader_state(),
|
||||||
m_status_thread(0),
|
m_status_thread(0),
|
||||||
m_closing(false) {
|
m_state(0) {
|
||||||
|
|
||||||
pthread_mutex_init(&m_mutex, NULL);
|
assert(uv_mutex_init(&m_mutex) == 0);
|
||||||
|
assert(uv_cond_init(&m_cond) == 0);
|
||||||
|
|
||||||
LONG result = SCardEstablishContext(SCARD_SCOPE_SYSTEM,
|
LONG result = SCardEstablishContext(SCARD_SCOPE_SYSTEM,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -51,13 +52,14 @@ PCSCLite::PCSCLite(): m_card_context(0),
|
|||||||
}
|
}
|
||||||
|
|
||||||
PCSCLite::~PCSCLite() {
|
PCSCLite::~PCSCLite() {
|
||||||
if (m_card_context) {
|
|
||||||
SCardReleaseContext(m_card_context);
|
if (m_status_thread) {
|
||||||
|
int ret = uv_thread_join(&m_status_thread);
|
||||||
|
assert(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_destroy(&m_mutex);
|
if (m_card_context) {
|
||||||
if (m_status_thread) {
|
SCardReleaseContext(m_card_context);
|
||||||
pthread_cancel(m_status_thread);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,8 +83,8 @@ NAN_METHOD(PCSCLite::Start) {
|
|||||||
async_baton->pcsclite = obj;
|
async_baton->pcsclite = obj;
|
||||||
|
|
||||||
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
uv_async_init(uv_default_loop(), &async_baton->async, (uv_async_cb)HandleReaderStatusChange);
|
||||||
pthread_create(&obj->m_status_thread, NULL, HandlerFunction, async_baton);
|
int ret = uv_thread_create(&obj->m_status_thread, HandlerFunction, async_baton);
|
||||||
pthread_detach(obj->m_status_thread);
|
assert(ret == 0);
|
||||||
|
|
||||||
NanReturnUndefined();
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
@@ -95,11 +97,24 @@ NAN_METHOD(PCSCLite::Close) {
|
|||||||
|
|
||||||
LONG result = SCARD_S_SUCCESS;
|
LONG result = SCARD_S_SUCCESS;
|
||||||
if (obj->m_pnp) {
|
if (obj->m_pnp) {
|
||||||
|
uv_mutex_lock(&obj->m_mutex);
|
||||||
|
if (obj->m_state == 0) {
|
||||||
|
obj->m_state = 1;
|
||||||
|
do {
|
||||||
result = SCardCancel(obj->m_card_context);
|
result = SCardCancel(obj->m_card_context);
|
||||||
} else {
|
} while (uv_cond_timedwait(&obj->m_cond, &obj->m_mutex, 10000000) != 0);
|
||||||
obj->m_closing = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&obj->m_mutex);
|
||||||
|
uv_mutex_destroy(&obj->m_mutex);
|
||||||
|
uv_cond_destroy(&obj->m_cond);
|
||||||
|
} else {
|
||||||
|
obj->m_state = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(uv_thread_join(&obj->m_status_thread) == 0);
|
||||||
|
obj->m_status_thread = 0;
|
||||||
|
|
||||||
NanReturnValue(NanNew<Number>(result));
|
NanReturnValue(NanNew<Number>(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +123,6 @@ void PCSCLite::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
NanScope();
|
NanScope();
|
||||||
|
|
||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(handle->data);
|
||||||
PCSCLite* pcsclite = async_baton->pcsclite;
|
|
||||||
AsyncResult* ar = async_baton->async_result;
|
AsyncResult* ar = async_baton->async_result;
|
||||||
|
|
||||||
if (ar->do_exit) {
|
if (ar->do_exit) {
|
||||||
@@ -137,19 +151,16 @@ void PCSCLite::HandleReaderStatusChange(uv_async_t *handle, int status) {
|
|||||||
ar->readers_name = NULL;
|
ar->readers_name = NULL;
|
||||||
ar->readers_name_length = 0;
|
ar->readers_name_length = 0;
|
||||||
ar->result = SCARD_S_SUCCESS;
|
ar->result = SCARD_S_SUCCESS;
|
||||||
/* Unlock the mutex */
|
|
||||||
pthread_mutex_unlock(&pcsclite->m_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* PCSCLite::HandlerFunction(void* arg) {
|
void PCSCLite::HandlerFunction(void* arg) {
|
||||||
|
|
||||||
LONG result = SCARD_S_SUCCESS;
|
LONG result = SCARD_S_SUCCESS;
|
||||||
AsyncBaton* async_baton = static_cast<AsyncBaton*>(arg);
|
AsyncBaton* async_baton = static_cast<AsyncBaton*>(arg);
|
||||||
PCSCLite* pcsclite = async_baton->pcsclite;
|
PCSCLite* pcsclite = async_baton->pcsclite;
|
||||||
async_baton->async_result = new AsyncResult();
|
async_baton->async_result = new AsyncResult();
|
||||||
while (!pcsclite->m_closing && (result == SCARD_S_SUCCESS)) {
|
|
||||||
/* Lock mutex. It'll be unlocked after the callback has been sent */
|
while (!pcsclite->m_state && (result == SCARD_S_SUCCESS)) {
|
||||||
pthread_mutex_lock(&pcsclite->m_mutex);
|
|
||||||
/* Get card readers */
|
/* Get card readers */
|
||||||
result = pcsclite->get_card_readers(pcsclite, async_baton->async_result);
|
result = pcsclite->get_card_readers(pcsclite, async_baton->async_result);
|
||||||
if (result == SCARD_E_NO_READERS_AVAILABLE) {
|
if (result == SCARD_E_NO_READERS_AVAILABLE) {
|
||||||
@@ -160,12 +171,26 @@ void* PCSCLite::HandlerFunction(void* arg) {
|
|||||||
async_baton->async_result->result = result;
|
async_baton->async_result->result = result;
|
||||||
/* Notify the nodejs thread */
|
/* Notify the nodejs thread */
|
||||||
uv_async_send(&async_baton->async);
|
uv_async_send(&async_baton->async);
|
||||||
|
|
||||||
if (pcsclite->m_pnp) {
|
if (pcsclite->m_pnp) {
|
||||||
|
/* Set current status */
|
||||||
|
pcsclite->m_card_reader_state.dwCurrentState =
|
||||||
|
pcsclite->m_card_reader_state.dwEventState;
|
||||||
/* Start checking for status change */
|
/* Start checking for status change */
|
||||||
result = SCardGetStatusChange(pcsclite->m_card_context,
|
result = SCardGetStatusChange(pcsclite->m_card_context,
|
||||||
INFINITE,
|
INFINITE,
|
||||||
&pcsclite->m_card_reader_state,
|
&pcsclite->m_card_reader_state,
|
||||||
1);
|
1);
|
||||||
|
uv_mutex_lock(&pcsclite->m_mutex);
|
||||||
|
if (pcsclite->m_state) {
|
||||||
|
uv_cond_signal(&pcsclite->m_cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != SCARD_S_SUCCESS) {
|
||||||
|
pcsclite->m_state = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_mutex_unlock(&pcsclite->m_mutex);
|
||||||
} else {
|
} else {
|
||||||
/* If PnP is not supported, just wait for 1 second */
|
/* If PnP is not supported, just wait for 1 second */
|
||||||
sleep(1);
|
sleep(1);
|
||||||
@@ -174,8 +199,6 @@ void* PCSCLite::HandlerFunction(void* arg) {
|
|||||||
|
|
||||||
async_baton->async_result->do_exit = true;
|
async_baton->async_result->do_exit = true;
|
||||||
uv_async_send(&async_baton->async);
|
uv_async_send(&async_baton->async);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCSCLite::CloseCallback(uv_handle_t *handle) {
|
void PCSCLite::CloseCallback(uv_handle_t *handle) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class PCSCLite: public node::ObjectWrap {
|
|||||||
static NAN_METHOD(Close);
|
static NAN_METHOD(Close);
|
||||||
|
|
||||||
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
static void HandleReaderStatusChange(uv_async_t *handle, int status);
|
||||||
static void* HandlerFunction(void* arg);
|
static void HandlerFunction(void* arg);
|
||||||
static void CloseCallback(uv_handle_t *handle);
|
static void CloseCallback(uv_handle_t *handle);
|
||||||
|
|
||||||
LONG get_card_readers(PCSCLite* pcsclite, AsyncResult* async_result);
|
LONG get_card_readers(PCSCLite* pcsclite, AsyncResult* async_result);
|
||||||
@@ -50,10 +50,11 @@ class PCSCLite: public node::ObjectWrap {
|
|||||||
|
|
||||||
SCARDCONTEXT m_card_context;
|
SCARDCONTEXT m_card_context;
|
||||||
SCARD_READERSTATE m_card_reader_state;
|
SCARD_READERSTATE m_card_reader_state;
|
||||||
pthread_t m_status_thread;
|
uv_thread_t m_status_thread;
|
||||||
pthread_mutex_t m_mutex;
|
uv_mutex_t m_mutex;
|
||||||
|
uv_cond_t m_cond;
|
||||||
bool m_pnp;
|
bool m_pnp;
|
||||||
bool m_closing;
|
int m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PCSCLITE_H */
|
#endif /* PCSCLITE_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user