Re: [PATCH 3/3] vdservice: stop service on virtio failure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 09/16/2012 11:50 AM, Arnon Gilboa wrote:
read&  write are async, and their completion is handled by handle_event(),
which returns status used by service execute loop.
previously an error in GetOverlappedResult caused vdservice hang.

also removed _events_vdi_port_base field as part of a clean-up. Could have been a separate patch.

Other than that, looks good.

rhbz#839564
---
  vdservice/pci_vdi_port.cpp    |    3 ++-
  vdservice/pci_vdi_port.h      |    2 +-
  vdservice/vdi_port.h          |    2 +-
  vdservice/vdservice.cpp       |   13 +++++--------
  vdservice/virtio_vdi_port.cpp |   24 +++++++++++++++---------
  vdservice/virtio_vdi_port.h   |    6 +++---
  6 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/vdservice/pci_vdi_port.cpp b/vdservice/pci_vdi_port.cpp
index 4deace1..7466fbc 100644
--- a/vdservice/pci_vdi_port.cpp
+++ b/vdservice/pci_vdi_port.cpp
@@ -124,8 +124,9 @@ int PCIVDIPort::read()
      return n;
  }

-void PCIVDIPort::handle_event(int event)
+bool PCIVDIPort::handle_event(int event)
  {
      // do nothing - the event merely serves to wake us up, then we call read/write
      // at VDService::execute start of while(_running) loop.
+    return true;
  }
diff --git a/vdservice/pci_vdi_port.h b/vdservice/pci_vdi_port.h
index caa990f..fcc76dc 100644
--- a/vdservice/pci_vdi_port.h
+++ b/vdservice/pci_vdi_port.h
@@ -41,7 +41,7 @@ public:
      virtual int read();
      virtual unsigned get_num_events() { return PCI_VDI_PORT_EVENT_COUNT; }
      virtual void fill_events(HANDLE* handles);
-    virtual void handle_event(int event);
+    virtual bool handle_event(int event);

  private:
      HANDLE _handle;
diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h
index 50c4d29..a0fb20e 100644
--- a/vdservice/vdi_port.h
+++ b/vdservice/vdi_port.h
@@ -61,7 +61,7 @@ public:
      virtual bool init() = 0;
      virtual unsigned get_num_events() = 0;
      virtual void fill_events(HANDLE* handles) = 0;
-    virtual void handle_event(int event) = 0;
+    virtual bool handle_event(int event) = 0;
      virtual int write() = 0;
      virtual int read() = 0;

diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index b48cbeb..2b925fd 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -130,7 +130,6 @@ private:
      bool _running;
      VDLog* _log;
      unsigned _events_count;
-    unsigned _events_vdi_port_base;
  };

  VDService* VDService::_singleton = NULL;
@@ -185,7 +184,6 @@ VDService::VDService()
      , _running (false)
      , _log (NULL)
      , _events_count(0)
-    , _events_vdi_port_base(0)
  {
      ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info));
      ZeroMemory(&_pipe_state, sizeof(_pipe_state));
@@ -536,13 +534,12 @@ bool VDService::execute()
      vd_printf("created %s", _vdi_port->name());
      _events_count = VD_STATIC_EVENTS_COUNT + _vdi_port->get_num_events() + 1 /*for agent*/;
      _events = new HANDLE[_events_count];
-    _events_vdi_port_base = VD_STATIC_EVENTS_COUNT;
      ZeroMemory(_events, _events_count);
      vd_printf("Connected to server");
      _events[VD_EVENT_PIPE_READ] = _pipe_state.read.overlap.hEvent;
      _events[VD_EVENT_PIPE_WRITE] = _pipe_state.write.overlap.hEvent;
      _events[VD_EVENT_CONTROL] = _control_event;
-    _vdi_port->fill_events(&_events[_events_vdi_port_base]);
+    _vdi_port->fill_events(&_events[VD_STATIC_EVENTS_COUNT]);
      _chunk_size = _chunk_port = 0;
      read_pipe();
      while (_running) {
@@ -602,12 +599,12 @@ bool VDService::execute()
                          }
                      }
                  } else {
-                    if (wait_ret>= WAIT_OBJECT_0 + _events_vdi_port_base&&
-                        wait_ret<  WAIT_OBJECT_0 +
-                                   _events_vdi_port_base + _vdi_port->get_num_events()) {
-                        _vdi_port->handle_event(wait_ret - VD_STATIC_EVENTS_COUNT - WAIT_OBJECT_0);
+                    int vdi_event = wait_ret - VD_STATIC_EVENTS_COUNT - WAIT_OBJECT_0;
+                    if (vdi_event>= 0&&  vdi_event<  _vdi_port->get_num_events()) {
+                        _running = _vdi_port->handle_event(vdi_event);
                      } else {
                          vd_printf("WaitForMultipleObjects failed %lu", GetLastError());
+                        _running = false;
                      }
                  }
              }
diff --git a/vdservice/virtio_vdi_port.cpp b/vdservice/virtio_vdi_port.cpp
index 92eb129..be5568a 100644
--- a/vdservice/virtio_vdi_port.cpp
+++ b/vdservice/virtio_vdi_port.cpp
@@ -51,17 +51,21 @@ void VirtioVDIPort::fill_events(HANDLE* handles) {
      handles[VIRTIO_VDI_PORT_EVENT_READ] = _read.overlap.hEvent;
  }

-void VirtioVDIPort::handle_event(int event) {
+bool VirtioVDIPort::handle_event(int event) {
+    bool ret;
+
      switch (event) {
          case VIRTIO_VDI_PORT_EVENT_WRITE:
-            write_completion();
+            ret = write_completion();
              break;
          case VIRTIO_VDI_PORT_EVENT_READ:
-            read_completion();
+            ret = read_completion();
              break;
          default:
              vd_printf("ERROR: unexpected event %d", event);
+            ret = false;
      }
+    return ret;
  }

  bool VirtioVDIPort::init()
@@ -113,20 +117,21 @@ int VirtioVDIPort::write()
      return ret;
  }

-void VirtioVDIPort::write_completion()
+bool VirtioVDIPort::write_completion()
  {
      DWORD bytes;

      if (!_write.pending) {
-        return;
+        return true;
      }
      if (!GetOverlappedResult(_handle,&_write.overlap,&bytes, FALSE)) {
          vd_printf("GetOverlappedResult failed: %lu", GetLastError());
-        return;
+        return false;
      }
      _write.start = _write.ring + (_write.start - _write.ring + bytes) % BUF_SIZE;
      _write.bytes = bytes;
      _write.pending = false;
+    return true;
  }

  int VirtioVDIPort::read()
@@ -160,7 +165,7 @@ int VirtioVDIPort::read()
      return ret;
  }

-void VirtioVDIPort::read_completion()
+bool VirtioVDIPort::read_completion()
  {
      DWORD bytes;

@@ -169,13 +174,14 @@ void VirtioVDIPort::read_completion()

          if (err == ERROR_OPERATION_ABORTED || err == ERROR_NO_SYSTEM_RESOURCES) {
              _read.pending = false;
-            return;
+            return true;
          } else if (err != ERROR_MORE_DATA) {
              vd_printf("GetOverlappedResult failed: %lu", err);
-            return;
+            return false;
          }
      }
      _read.end = _read.ring + (_read.end - _read.ring + bytes) % BUF_SIZE;
      _read.bytes = bytes;
      _read.pending = false;
+    return true;
  }
diff --git a/vdservice/virtio_vdi_port.h b/vdservice/virtio_vdi_port.h
index 15b6811..d72edf4 100644
--- a/vdservice/virtio_vdi_port.h
+++ b/vdservice/virtio_vdi_port.h
@@ -17,13 +17,13 @@ public:
      virtual bool init();
      virtual unsigned get_num_events() { return VIRTIO_VDI_PORT_EVENT_COUNT; }
      virtual void fill_events(HANDLE* handles);
-    virtual void handle_event(int event);
+    virtual bool handle_event(int event);
      virtual int write();
      virtual int read();

  private:
-    void write_completion();
-    void read_completion();
+    bool write_completion();
+    bool read_completion();

  private:
      static VirtioVDIPort* _singleton;

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]