summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2018-05-15 00:27:52 +0200
committerGravatar Nikias Bassen2018-05-15 00:27:52 +0200
commit08d9ec01cf59c7bb3febe3c4600e9efeb81901e3 (patch)
tree8b09520d8b31c5153c9a458d1a596264c21cdf3c /src
parentca6f4718deb56367bbae33312e0f341e0595f3eb (diff)
downloadusbmuxd-08d9ec01cf59c7bb3febe3c4600e9efeb81901e3.tar.gz
usbmuxd-08d9ec01cf59c7bb3febe3c4600e9efeb81901e3.tar.bz2
device: Flush buffer to client when remote side unexpectedly terminates connection
Diffstat (limited to 'src')
-rw-r--r--src/client.c3
-rw-r--r--src/device.c15
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);