aboutsummaryrefslogtreecommitdiff
path: root/client/acronc/handler_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/acronc/handler_socket.c')
-rw-r--r--client/acronc/handler_socket.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/client/acronc/handler_socket.c b/client/acronc/handler_socket.c
index 2dfda5e..c0a9923 100644
--- a/client/acronc/handler_socket.c
+++ b/client/acronc/handler_socket.c
@@ -125,50 +125,50 @@ static void on_read(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) {
}
int r;
ac_obj_t *obj = NULL;
- if ((r = ac_receive(ac_conn, buf->base, nread, &obj))) {
- LOGEV("Cannot parse the response (%d).", r);
- /* libac error. Socket is working. */
- ex(false);
- return;
- }
-
- if (!ready) {
- enum ac_connection_state state;
- if ((r = ac_get_state(ac_conn, &state))) {
- LOGEV("Cannot get state (%d).", r);
+ size_t pos = 0;
+ size_t read = 0;
+ bool again = false;
+ while (read < nread || again) {
+ if (again) {
+ LOGD("Clearing backlog.");
+ r = ac_receive(ac_conn, NULL, 0, 0, &obj, NULL);
+ again = false;
+ } else {
+ r = ac_receive(ac_conn, buf->base, pos, nread, &obj, &read);
+ pos += read;
+ }
+ if (r == AC_E_AGAIN) {
+ again = true;
+ } else if (r) {
+ LOGEV("Cannot parse the response (%d).", r);
/* libac error. Socket is working. */
ex(false);
+ free(buf->base);
return;
}
- if (state == AC_STATE_READY) {
- ready = true;
- if ((cb_ready())) {
- /* acronc error. Socket is working. */
- ex(false);
- return;
- }
- }
- }
- if (obj) {
- LOGDV("Got object: %p", obj);
- /* uv_async_send is unreliable, and missed messages will cause memory leak. */
- if (cb_recv(obj)) {
- /* acronc error. Socket is working. */
- ex(false);
- }
- LOGD("Clearing backlog.");
- while (true) {
- if ((r = ac_receive(ac_conn, NULL, 0, &obj))) {
- LOGEV("Cannot clear backlog (%d).", r);
+ if (!ready) {
+ enum ac_connection_state state;
+ if ((r = ac_get_state(ac_conn, &state))) {
+ LOGEV("Cannot get state (%d).", r);
/* libac error. Socket is working. */
free(buf->base);
ex(false);
return;
}
- if (!obj) {
- break;
+ if (state == AC_STATE_READY) {
+ ready = true;
+ if ((cb_ready())) {
+ /* acronc error. Socket is working. */
+ free(buf->base);
+ ex(false);
+ return;
+ }
}
+ }
+ if (obj) {
+ LOGDV("Got object: %p", obj);
+ /* uv_async_send is unreliable, and missed messages will cause memory leak. */
if (cb_recv(obj)) {
/* acronc error. Socket is working. */
ex(false);