| 134 | } |
| 135 | |
| 136 | ssize_t async_pipe_read(hamlib_async_pipe_t *pipe, void *buf, size_t count, |
| 137 | int timeout) |
| 138 | { |
| 139 | HANDLE event_handles[1] = |
| 140 | { |
| 141 | pipe->read_overlapped.hEvent, |
| 142 | }; |
| 143 | HANDLE read_handle = pipe->read; |
| 144 | LPOVERLAPPED overlapped = &pipe->read_overlapped; |
| 145 | DWORD wait_result; |
| 146 | int result; |
| 147 | ssize_t bytes_read = 0; |
| 148 | |
| 149 | result = ReadFile(read_handle, buf, count, NULL, overlapped); |
| 150 | |
| 151 | if (!result) |
| 152 | { |
| 153 | result = GetLastError(); |
| 154 | |
| 155 | switch (result) |
| 156 | { |
| 157 | case ERROR_SUCCESS: |
| 158 | // No error? |
| 159 | break; |
| 160 | |
| 161 | case ERROR_IO_PENDING: |
| 162 | wait_result = WaitForMultipleObjects(1, event_handles, FALSE, timeout); |
| 163 | |
| 164 | switch (wait_result) |
| 165 | { |
| 166 | case WAIT_OBJECT_0 + 0: |
| 167 | break; |
| 168 | |
| 169 | case WAIT_TIMEOUT: |
| 170 | if (count == 0) |
| 171 | { |
| 172 | // Zero-length reads are used to wait for incoming data, |
| 173 | // so the I/O operation needs to be cancelled in case of a timeout |
| 174 | CancelIo(read_handle); |
| 175 | return -RIG_ETIMEOUT; |
| 176 | } |
| 177 | else |
| 178 | { |
| 179 | // Should not happen, as reads with count > 0 are used only when there is data available in the pipe |
| 180 | return -RIG_EINTERNAL; |
| 181 | } |
| 182 | |
| 183 | default: |
| 184 | result = GetLastError(); |
| 185 | rig_debug(RIG_DEBUG_ERR, "%s: WaitForMultipleObjects() error: %d\n", __func__, |
| 186 | result); |
| 187 | return -RIG_EINTERNAL; |
| 188 | } |
| 189 | |
| 190 | break; |
| 191 | |
| 192 | default: |
| 193 | rig_debug(RIG_DEBUG_ERR, "%s: ReadFile() error: %d\n", __func__, result); |
no test coverage detected