| 475 | } |
| 476 | |
| 477 | static int port_read_sync_data(hamlib_port_t *p, void *buf, size_t count) |
| 478 | { |
| 479 | // Wait for data in both the response data pipe and the error code pipe to detect errors occurred during read |
| 480 | LARGE_INTEGER timeout; |
| 481 | HANDLE hLocal = CreateWaitableTimer(NULL, FALSE, NULL); |
| 482 | HANDLE event_handles[3] = |
| 483 | { |
| 484 | p->sync_data_pipe->read_overlapped.hEvent, |
| 485 | p->sync_data_error_pipe->read_overlapped.hEvent, |
| 486 | hLocal |
| 487 | }; |
| 488 | HANDLE read_handle = p->sync_data_pipe->read; |
| 489 | LPOVERLAPPED overlapped = &p->sync_data_pipe->read_overlapped; |
| 490 | DWORD wait_result; |
| 491 | int result; |
| 492 | ssize_t bytes_read; |
| 493 | |
| 494 | result = ReadFile(p->sync_data_pipe->read, buf, count, NULL, overlapped); |
| 495 | |
| 496 | if (!result) |
| 497 | { |
| 498 | result = GetLastError(); |
| 499 | |
| 500 | switch (result) |
| 501 | { |
| 502 | case ERROR_SUCCESS: |
| 503 | // No error? |
| 504 | break; |
| 505 | |
| 506 | case ERROR_IO_PENDING: |
| 507 | timeout.QuadPart = (p->timeout * -1000000LL); |
| 508 | |
| 509 | if ((result = SetWaitableTimer(hLocal, &timeout, 0, NULL, NULL, 0)) == 0) |
| 510 | { |
| 511 | rig_debug(RIG_DEBUG_ERR, "%s: SetWaitableTimer error: %d\n", __func__, result); |
| 512 | wait_result = WaitForMultipleObjects(3, event_handles, FALSE, INFINITE); |
| 513 | } |
| 514 | else |
| 515 | { |
| 516 | wait_result = WaitForMultipleObjects(3, event_handles, FALSE, p->timeout); |
| 517 | } |
| 518 | |
| 519 | |
| 520 | switch (wait_result) |
| 521 | { |
| 522 | case WAIT_OBJECT_0 + 0: |
| 523 | break; |
| 524 | |
| 525 | case WAIT_OBJECT_0 + 1: |
| 526 | return port_read_sync_data_error_code(p); |
| 527 | |
| 528 | case WAIT_OBJECT_0 + 2: |
| 529 | if (count == 0) |
| 530 | { |
| 531 | CancelIo(read_handle); |
| 532 | return -RIG_ETIMEOUT; |
| 533 | } |
| 534 | else |
no test coverage detected