migration: handle EAGAIN while reading QEMUFile
This will never happen right now (the assertion would fail). The next patch will set the socket or pipe in non-blocking mode, thus enabling this part of the code. Coroutines can just stop whenever they want with qemu_coroutine_yield. As soon as select tells the main loop that the migration stream is readable, the coroutine is re-entered directly in qemu_get_buffer, where it will read more data and pass it to the loading routines. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
1c12e1f5b2
commit
595ab64169
30
savevm.c
30
savevm.c
@ -200,13 +200,22 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||
QEMUFileSocket *s = opaque;
|
||||
ssize_t len;
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
len = qemu_recv(s->fd, buf, size, 0);
|
||||
} while (len == -1 && socket_error() == EINTR);
|
||||
if (len != -1) {
|
||||
break;
|
||||
}
|
||||
if (socket_error() == EAGAIN) {
|
||||
assert(qemu_in_coroutine());
|
||||
qemu_coroutine_yield();
|
||||
} else if (socket_error() != EINTR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == -1)
|
||||
if (len == -1) {
|
||||
len = -socket_error();
|
||||
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -237,10 +246,19 @@ static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||
FILE *fp = s->stdio_file;
|
||||
int bytes;
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
clearerr(fp);
|
||||
bytes = fread(buf, 1, size, fp);
|
||||
} while ((bytes == 0) && ferror(fp) && (errno == EINTR));
|
||||
if (bytes != 0 || !ferror(fp)) {
|
||||
break;
|
||||
}
|
||||
if (errno == EAGAIN) {
|
||||
assert(qemu_in_coroutine());
|
||||
qemu_coroutine_yield();
|
||||
} else if (errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user