}
}
+/* recv_lock should be unlocked before return */
static int proto_recv_single(int fd, recv_callback callback, void *user_data)
{
int r;
assert(callback);
r = proto_recv(fd, &type, &data, &len);
- if (r == -1)
+ pthread_mutex_unlock(&recv_lock);
+
+ if (r == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
return -1;
+ }
callback(user_data, type, data, len);
free(data);
return 0;
}
+/* recv_lock should be unlocked before return */
static int proto_recv_frag(int fd, struct header *hdr,
recv_callback callback, void *user_data)
{
assert(hdr);
assert(callback);
- pthread_mutex_lock(&recv_lock);
switch (hdr->type) {
case MSG_FIRST:
rif = add_rif(fd, hdr, callback, user_data);
return -1;
}
+ pthread_mutex_lock(&recv_lock);
r = recv(fd, &hdr, sizeof(hdr), MSG_PEEK);
if (r <= 0) {
+ pthread_mutex_unlock(&recv_lock);
if (r == 0) {
bxt_dbg("recv: fd %d closed", fd);
} else {
r = recv(fd, &hdr, sizeof(hdr), 0);
if (r <= 0) {
- if (r == 0)
+ if (r == 0) {
bxt_dbg("recv: fd %d closed", fd);
- else
- bxt_err("recv: fd %d errno %d", fd, errno);
+ } else {
+ if (errno != EAGAIN && errno != EINTR)
+ bxt_err("recv: fd %d errno %d", fd, errno);
+ }
return -1;
}
r = recv(fd, _data, hdr.total, 0);
if (r <= 0) {
- if (r == 0)
+ if (r == 0) {
bxt_dbg("recv: fd %d closed", fd);
- else
- bxt_err("recv: fd %d errno %d", fd, errno);
+ } else {
+ if (errno != EAGAIN && errno != EINTR)
+ bxt_err("recv: fd %d errno %d", fd, errno);
+ }
free(_data);