diff options
| author | 2018-05-15 00:27:52 +0200 | |
|---|---|---|
| committer | 2018-05-15 00:27:52 +0200 | |
| commit | 08d9ec01cf59c7bb3febe3c4600e9efeb81901e3 (patch) | |
| tree | 8b09520d8b31c5153c9a458d1a596264c21cdf3c | |
| parent | ca6f4718deb56367bbae33312e0f341e0595f3eb (diff) | |
| download | usbmuxd-08d9ec01cf59c7bb3febe3c4600e9efeb81901e3.tar.gz usbmuxd-08d9ec01cf59c7bb3febe3c4600e9efeb81901e3.tar.bz2 | |
device: Flush buffer to client when remote side unexpectedly terminates connection
| -rw-r--r-- | src/client.c | 3 | ||||
| -rw-r--r-- | src/device.c | 15 |
2 files changed, 16 insertions, 2 deletions
diff --git a/src/client.c b/src/client.c index a9c986a..bbdac84 100644 --- a/src/client.c +++ b/src/client.c | |||
| @@ -113,7 +113,8 @@ int client_write(struct mux_client *client, void *buffer, uint32_t len) | |||
| 113 | sret = send(client->fd, buffer, len, 0); | 113 | sret = send(client->fd, buffer, len, 0); |
| 114 | if (sret < 0) { | 114 | if (sret < 0) { |
| 115 | if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { | 115 | if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { |
| 116 | usbmuxd_log(LL_ERROR, "ERROR: client_write: fd %d not ready for writing", client->fd); | 116 | usbmuxd_log(LL_DEBUG, "client_write: fd %d not ready for writing", client->fd); |
| 117 | sret = 0; | ||
| 117 | } else { | 118 | } else { |
| 118 | usbmuxd_log(LL_ERROR, "ERROR: client_write: sending to fd %d failed: %s", client->fd, strerror(errno)); | 119 | usbmuxd_log(LL_ERROR, "ERROR: client_write: sending to fd %d failed: %s", client->fd, strerror(errno)); |
| 119 | } | 120 | } |
diff --git a/src/device.c b/src/device.c index d5cf9f0..3edaea0 100644 --- a/src/device.c +++ b/src/device.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <stdint.h> | 32 | #include <stdint.h> |
| 33 | #include <inttypes.h> | 33 | #include <inttypes.h> |
| 34 | #include <pthread.h> | 34 | #include <pthread.h> |
| 35 | #include <unistd.h> | ||
| 35 | #include "device.h" | 36 | #include "device.h" |
| 36 | #include "client.h" | 37 | #include "client.h" |
| 37 | #include "preflight.h" | 38 | #include "preflight.h" |
| @@ -314,10 +315,21 @@ static void connection_teardown(struct mux_connection *conn) | |||
| 314 | } else { | 315 | } else { |
| 315 | conn->state = CONN_DEAD; | 316 | conn->state = CONN_DEAD; |
| 316 | if((conn->events & POLLOUT) && conn->ib_size > 0){ | 317 | if((conn->events & POLLOUT) && conn->ib_size > 0){ |
| 318 | usbmuxd_log(LL_DEBUG, "%s: flushing buffer to client (%u bytes)", __func__, conn->ib_size); | ||
| 319 | uint64_t tm_last = mstime64(); | ||
| 317 | while(1){ | 320 | while(1){ |
| 318 | size = client_write(conn->client, conn->ib_buf, conn->ib_size); | 321 | size = client_write(conn->client, conn->ib_buf, conn->ib_size); |
| 319 | if(size <= 0) { | 322 | if(size < 0) { |
| 323 | usbmuxd_log(LL_ERROR, "%s: aborting buffer flush to client after error.", __func__); | ||
| 320 | break; | 324 | break; |
| 325 | } else if (size == 0) { | ||
| 326 | uint64_t tm_now = mstime64(); | ||
| 327 | if (tm_now - tm_last > 1000) { | ||
| 328 | usbmuxd_log(LL_ERROR, "%s: aborting buffer flush to client after unsuccessfully attempting for %dms.", __func__, (int)(tm_now - tm_last)); | ||
| 329 | break; | ||
| 330 | } | ||
| 331 | usleep(10000); | ||
| 332 | continue; | ||
| 321 | } | 333 | } |
| 322 | if(size == (int)conn->ib_size) { | 334 | if(size == (int)conn->ib_size) { |
| 323 | conn->ib_size = 0; | 335 | conn->ib_size = 0; |
| @@ -326,6 +338,7 @@ static void connection_teardown(struct mux_connection *conn) | |||
| 326 | conn->ib_size -= size; | 338 | conn->ib_size -= size; |
| 327 | memmove(conn->ib_buf, conn->ib_buf + size, conn->ib_size); | 339 | memmove(conn->ib_buf, conn->ib_buf + size, conn->ib_size); |
| 328 | } | 340 | } |
| 341 | tm_last = mstime64(); | ||
| 329 | } | 342 | } |
| 330 | } | 343 | } |
| 331 | client_close(conn->client); | 344 | client_close(conn->client); |
