static int goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id ) { PipeDevice* dev = opaque; Pipe* pipe; if (version_id != GOLDFISH_PIPE_SAVE_VERSION) return -EINVAL; dev->address = qemu_get_be32(file); dev->size = qemu_get_be32(file); dev->status = qemu_get_be32(file); dev->channel = qemu_get_be32(file); dev->wakes = qemu_get_be32(file); dev->params_addr = qemu_get_be64(file); int count = qemu_get_sbe32(file); for ( ; count > 0; count-- ) { pipe = pipe_load(dev, file); if (pipe == NULL) { return -EIO; } pipe->next = dev->pipes; dev->pipes = pipe; } for ( pipe = dev->pipes; pipe; pipe = pipe->next ) { if (pipe->wanted != 0) goldfish_pipe_wake(pipe, pipe->wanted); if (pipe->closed != 0) goldfish_pipe_close(pipe); } return 0; }
/* This function is only called when the socket is disconnected. * See netPipe_closeFromGuest() for the case when the guest requires * the disconnection. */ static void netPipe_closeFromSocket( void* opaque ) { NetPipe* pipe = opaque; D("%s", __FUNCTION__); /* If the guest already ordered the pipe to be closed, delete immediately */ if (pipe->state == STATE_CLOSING_GUEST) { netPipe_free(pipe); return; } /* Force the closure of the QEMUD channel - if a guest is blocked * waiting for a wake signal, it will receive an error. */ if (pipe->hwpipe != NULL) { goldfish_pipe_close(pipe->hwpipe); pipe->hwpipe = NULL; } pipe->state = STATE_CLOSING_SOCKET; netPipe_resetState(pipe); }