Skip to content

Commit c1d9d88

Browse files
kimushureconbot
authored andcommitted
fix(windows): Fix async handle leak (#1367)
Fixes event loop weirdness in #1363
1 parent 0e4b1f9 commit c1d9d88

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

src/serialport_win.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ void ErrorCodeToString(const char* prefix, int errorCode, char *errorStr) {
3939
}
4040
}
4141

42+
void AsyncCloseCallback(uv_handle_t* handle)
43+
{
44+
uv_async_t* async = (uv_async_t*)handle;
45+
delete async;
46+
}
47+
4248
void EIO_Open(uv_work_t* req) {
4349
OpenBaton* data = static_cast<OpenBaton*>(req->data);
4450

@@ -293,9 +299,13 @@ NAN_METHOD(Write) {
293299
baton->offset = 0;
294300
baton->callback.Reset(info[2].As<v8::Function>());
295301
baton->complete = false;
302+
303+
uv_async_t* async = new uv_async_t;
304+
uv_async_init(uv_default_loop(), async, EIO_AfterWrite);
305+
async->data = baton;
296306
// WriteFileEx requires a thread that can block. Create a new thread to
297307
// run the write operation, saving the handle so it can be deallocated later.
298-
baton->hThread = CreateThread(NULL, 0, WriteThread, baton, 0, NULL);
308+
baton->hThread = CreateThread(NULL, 0, WriteThread, async, 0, NULL);
299309
}
300310

301311
void __stdcall WriteIOCompletion(DWORD errorCode, DWORD bytesTransferred, OVERLAPPED* ov) {
@@ -316,7 +326,8 @@ void __stdcall WriteIOCompletion(DWORD errorCode, DWORD bytesTransferred, OVERLA
316326
}
317327

318328
DWORD __stdcall WriteThread(LPVOID param) {
319-
WriteBaton* baton = static_cast<WriteBaton*>(param);
329+
uv_async_t* async = static_cast<uv_async_t*>(param);
330+
WriteBaton* baton = static_cast<WriteBaton*>(async->data);
320331

321332
OVERLAPPED* ov = new OVERLAPPED;
322333
memset(ov, 0, sizeof(OVERLAPPED));
@@ -338,9 +349,6 @@ DWORD __stdcall WriteThread(LPVOID param) {
338349
}
339350
delete ov;
340351
// Signal the main thread to run the callback.
341-
uv_async_t* async = new uv_async_t;
342-
uv_async_init(uv_default_loop(), async, EIO_AfterWrite);
343-
async->data = baton;
344352
uv_async_send(async);
345353
ExitThread(0);
346354
}
@@ -350,7 +358,7 @@ void EIO_AfterWrite(uv_async_t* req) {
350358
WriteBaton* baton = static_cast<WriteBaton*>(req->data);
351359
WaitForSingleObject(baton->hThread, INFINITE);
352360
CloseHandle(baton->hThread);
353-
delete req;
361+
uv_close((uv_handle_t*)req, AsyncCloseCallback);
354362

355363
v8::Local<v8::Value> argv[1];
356364
if (baton->errorString[0]) {
@@ -411,6 +419,10 @@ NAN_METHOD(Read) {
411419
baton->bufferData = node::Buffer::Data(buffer);
412420
baton->callback.Reset(info[4].As<v8::Function>());
413421
baton->complete = false;
422+
423+
uv_async_t* async = new uv_async_t;
424+
uv_async_init(uv_default_loop(), async, EIO_AfterRead);
425+
async->data = baton;
414426
// ReadFileEx requires a thread that can block. Create a new thread to
415427
// run the read operation, saving the handle so it can be deallocated later.
416428
baton->hThread = CreateThread(NULL, 0, ReadThread, baton, 0, NULL);
@@ -482,7 +494,8 @@ void __stdcall ReadIOCompletion(DWORD errorCode, DWORD bytesTransferred, OVERLAP
482494
}
483495

484496
DWORD __stdcall ReadThread(LPVOID param) {
485-
ReadBaton* baton = static_cast<ReadBaton*>(param);
497+
uv_async_t* async = static_cast<uv_async_t*>(param);
498+
ReadBaton* baton = static_cast<ReadBaton*>(async->data);
486499
DWORD lastError;
487500

488501
OVERLAPPED* ov = new OVERLAPPED;
@@ -516,9 +529,6 @@ DWORD __stdcall ReadThread(LPVOID param) {
516529
}
517530
delete ov;
518531
// Signal the main thread to run the callback.
519-
uv_async_t* async = new uv_async_t;
520-
uv_async_init(uv_default_loop(), async, EIO_AfterRead);
521-
async->data = baton;
522532
uv_async_send(async);
523533
ExitThread(0);
524534
}
@@ -528,7 +538,7 @@ void EIO_AfterRead(uv_async_t* req) {
528538
ReadBaton* baton = static_cast<ReadBaton*>(req->data);
529539
WaitForSingleObject(baton->hThread, INFINITE);
530540
CloseHandle(baton->hThread);
531-
delete req;
541+
uv_close((uv_handle_t*)req, AsyncCloseCallback);
532542

533543
v8::Local<v8::Value> argv[2];
534544
if (baton->errorString[0]) {

0 commit comments

Comments
 (0)