diff options
author | Alon Levy <alevy@redhat.com> | 2010-12-29 17:54:23 +0200 |
---|---|---|
committer | Arnon Gilboa <agilboa@agilboa.usersys.redhat.com> | 2011-01-11 17:18:02 +0200 |
commit | 935330f996535f7d59963978fc8fdb17bf1d75cb (patch) | |
tree | d5870b6da3b0c3e39ae2ef30ac9390dfc6907a9c | |
parent | 904b0860b331832d9c274731ac65709df4932242 (diff) |
vdi_port refactor: move ring handling to VDIPort, split h file, remove some debug prints
-rw-r--r-- | vdservice/vdi_port.cpp | 76 | ||||
-rw-r--r-- | vdservice/vdi_port.h | 57 | ||||
-rw-r--r-- | vdservice/vdservice.cpp | 4 | ||||
-rw-r--r-- | vdservice/virtio_vdi_port.cpp | 78 | ||||
-rw-r--r-- | vdservice/virtio_vdi_port.h | 44 |
5 files changed, 136 insertions, 123 deletions
diff --git a/vdservice/vdi_port.cpp b/vdservice/vdi_port.cpp new file mode 100644 index 0000000..f9fbcdf --- /dev/null +++ b/vdservice/vdi_port.cpp @@ -0,0 +1,76 @@ +#include "vdi_port.h"
+
+VDIPort::VDIPort()
+{
+ ZeroMemory(&_write, offsetof(VDIPortBuffer, ring)); + _write.start = _write.end = _write.ring; + ZeroMemory(&_read, offsetof(VDIPortBuffer, ring)); + _read.start = _read.end = _read.ring; +} + + +size_t VDIPort::read_ring_size() +{ + return (BUF_SIZE + _read.end - _read.start) % BUF_SIZE; +} + +size_t VDIPort::write_ring_free_space() +{ + return (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE; +} + +size_t VDIPort::ring_write(const void* buf, size_t size) +{ + size_t free_size = (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE; + size_t n; + + if (size > free_size) { + size = free_size; + } + if (_write.end < _write.start) { + memcpy(_write.end, buf, size); + } else { + n = MIN(size, (size_t)(&_write.ring[BUF_SIZE] - _write.end)); + memcpy(_write.end, buf, n); + if (size > n) { + memcpy(_write.ring, (uint8_t*)buf + n, size - n); + } + } + _write.end = _write.ring + (_write.end - _write.ring + size) % BUF_SIZE; + return size; +} + +size_t VDIPort::read_ring_continuous_remaining_size() +{ + DWORD size; + + if (_read.start <= _read.end) { + size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end)); + } else { + size = (DWORD)(_read.start - _read.end - 1); + } + return size; +} + +size_t VDIPort::ring_read(void* buf, size_t size) +{ + size_t n; + size_t m = 0; + + if (_read.start == _read.end) { + return 0; + } + if (_read.start < _read.end) { + n = MIN(size, (size_t)(_read.end - _read.start)); + memcpy(buf, _read.start, n); + } else { + n = MIN(size, (size_t)(&_read.ring[BUF_SIZE] - _read.start)); + memcpy(buf, _read.start, n); + if (size > n) { + m = MIN(size - n, (size_t)(_read.end - _read.ring)); + memcpy((uint8_t*)buf + n, _read.ring, m); + } + } + _read.start = _read.ring + (_read.start - _read.ring + n + m) % BUF_SIZE; + return n + m; +} diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h index 2d2b2d2..cc4cb53 100644 --- a/vdservice/vdi_port.h +++ b/vdservice/vdi_port.h @@ -21,6 +21,8 @@ #include <windows.h> #include <stdint.h> +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + #define BUF_SIZE (1024 * 1024) #define VDI_PORT_BLOCKED 0 @@ -38,62 +40,25 @@ typedef struct VDIPortBuffer { class VDIPort { public: + VDIPort(); virtual ~VDIPort() {} + + size_t ring_write(const void* buf, size_t size); + size_t write_ring_free_space(); + size_t ring_read(void* buf, size_t size); + size_t read_ring_size(); + size_t read_ring_continuous_remaining_size(); + virtual bool init() = 0; - virtual size_t ring_write(const void* buf, size_t size) = 0; - virtual size_t write_ring_free_space() = 0; - virtual size_t ring_read(void* buf, size_t size) = 0; - virtual size_t read_ring_size() = 0; - virtual size_t read_ring_continuous_remaining_size() = 0; virtual unsigned get_num_events() = 0; virtual void fill_events(HANDLE *handle) = 0; virtual void handle_event(int event) = 0; virtual int write() = 0; virtual int read() = 0; -}; -class VirtioVDIPort : public VDIPort { -public: - VirtioVDIPort(); - ~VirtioVDIPort(); - virtual bool init(); - virtual size_t ring_write(const void* buf, size_t size); - virtual size_t write_ring_free_space(); - virtual size_t ring_read(void* buf, size_t size); - virtual size_t read_ring_size(); - virtual size_t read_ring_continuous_remaining_size(); - virtual unsigned get_num_events() { return 2; } - virtual void fill_events(HANDLE *handle) { - handle[0] = _write.overlap.hEvent; - handle[1] = _read.overlap.hEvent; - } - virtual void handle_event(int event) { - switch (event) { - case 0: write_completion(); break; - case 1: read_completion(); break; - } - } - virtual int write(); - virtual int read(); - -private: - void write_completion(); - void read_completion(); - int handle_error(); - -private: - static VirtioVDIPort* _singleton; - HANDLE _handle; +protected: VDIPortBuffer _write; VDIPortBuffer _read; }; -// Ring notes: -// _end is one after the end of data -// _start==_end means empty ring -// _start-1==_end (modulo) means full ring -// _start-1 is never used -// ring_write & read on right side of the ring (update _end) -// ring_read & write from left (update _start) - #endif diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp index 4c7785b..7b0cadb 100644 --- a/vdservice/vdservice.cpp +++ b/vdservice/vdservice.cpp @@ -22,7 +22,7 @@ #include <stdio.h> #include <tlhelp32.h> #include "vdcommon.h" -#include "vdi_port.h" +#include "virtio_vdi_port.h" //#define DEBUG_VDSERVICE @@ -450,8 +450,6 @@ bool VDService::execute() _events[VD_EVENT_CONTROL] = _control_event; _events[VD_EVENT_LOGON] = _logon_event; _agent_proc_info.hProcess; - vd_printf("Calling fill_events"); - vd_printf("&_events[VD_ENVETS_COUNT] == %p", &_events[VD_STATIC_EVENTS_COUNT]); _vdi_port->fill_events(&_events[_events_vdi_port_base]); _chunk_size = _chunk_port = 0; read_pipe(); diff --git a/vdservice/virtio_vdi_port.cpp b/vdservice/virtio_vdi_port.cpp index 8a7cf19..278a88b 100644 --- a/vdservice/virtio_vdi_port.cpp +++ b/vdservice/virtio_vdi_port.cpp @@ -16,7 +16,7 @@ */ #include "stdio.h" -#include "vdi_port.h" +#include "virtio_vdi_port.h" #include "vdlog.h" #define VIOSERIAL_PORT_PATH L"\\\\.\\Global\\com.redhat.spice.0" @@ -24,17 +24,12 @@ // Current limitation of virtio-serial windows driver (RHBZ 617000) #define VIOSERIAL_PORT_MAX_WRITE_BYTES 2048 -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - VirtioVDIPort* VirtioVDIPort::_singleton; VirtioVDIPort::VirtioVDIPort() - : _handle (INVALID_HANDLE_VALUE) + : VDIPort() + , _handle (INVALID_HANDLE_VALUE) { - ZeroMemory(&_write, offsetof(VDIPortBuffer, ring)); - _write.start = _write.end = _write.ring; - ZeroMemory(&_read, offsetof(VDIPortBuffer, ring)); - _read.start = _read.end = _read.ring; _singleton = this; } @@ -53,6 +48,7 @@ VirtioVDIPort::~VirtioVDIPort() bool VirtioVDIPort::init() { + vd_printf("creating VirtioVDIPort"); _handle = CreateFile(VIOSERIAL_PORT_PATH, GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (_handle == INVALID_HANDLE_VALUE) { @@ -72,32 +68,6 @@ bool VirtioVDIPort::init() return true; } -size_t VirtioVDIPort::write_ring_free_space() -{ - return (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE; -} - -size_t VirtioVDIPort::ring_write(const void* buf, size_t size) -{ - size_t free_size = (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE; - size_t n; - - if (size > free_size) { - size = free_size; - } - if (_write.end < _write.start) { - memcpy(_write.end, buf, size); - } else { - n = MIN(size, (size_t)(&_write.ring[BUF_SIZE] - _write.end)); - memcpy(_write.end, buf, n); - if (size > n) { - memcpy(_write.ring, (uint8_t*)buf + n, size - n); - } - } - _write.end = _write.ring + (_write.end - _write.ring + size) % BUF_SIZE; - return size; -} - int VirtioVDIPort::write() { int size; @@ -142,46 +112,6 @@ void VirtioVDIPort::write_completion() _write.pending = false; } -size_t VirtioVDIPort::read_ring_size() -{ - return (BUF_SIZE + _read.end - _read.start) % BUF_SIZE; -} - -size_t VirtioVDIPort::read_ring_continuous_remaining_size() -{ - DWORD size; - - if (_read.start <= _read.end) { - size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end)); - } else { - size = (DWORD)(_read.start - _read.end - 1); - } - return size; -} - -size_t VirtioVDIPort::ring_read(void* buf, size_t size) -{ - size_t n; - size_t m = 0; - - if (_read.start == _read.end) { - return 0; - } - if (_read.start < _read.end) { - n = MIN(size, (size_t)(_read.end - _read.start)); - memcpy(buf, _read.start, n); - } else { - n = MIN(size, (size_t)(&_read.ring[BUF_SIZE] - _read.start)); - memcpy(buf, _read.start, n); - if (size > n) { - m = MIN(size - n, (size_t)(_read.end - _read.ring)); - memcpy((uint8_t*)buf + n, _read.ring, m); - } - } - _read.start = _read.ring + (_read.start - _read.ring + n + m) % BUF_SIZE; - return n + m; -} - int VirtioVDIPort::read() { int size; diff --git a/vdservice/virtio_vdi_port.h b/vdservice/virtio_vdi_port.h new file mode 100644 index 0000000..6738804 --- /dev/null +++ b/vdservice/virtio_vdi_port.h @@ -0,0 +1,44 @@ +#ifndef _H_VIRTIO_VDI_PORT
+#define _H_VIRTIO_VDI_PORT
+
+#include "vdi_port.h"
+
+class VirtioVDIPort : public VDIPort {
+public:
+ VirtioVDIPort();
+ ~VirtioVDIPort();
+ virtual const char *name() { return "VirtioVDIPort"; } + virtual bool init();
+ virtual unsigned get_num_events() { return 2; }
+ virtual void fill_events(HANDLE *handle) {
+ handle[0] = _write.overlap.hEvent;
+ handle[1] = _read.overlap.hEvent;
+ }
+ virtual void handle_event(int event) {
+ switch (event) {
+ case 0: write_completion(); break;
+ case 1: read_completion(); break;
+ }
+ }
+ virtual int write();
+ virtual int read();
+
+private:
+ void write_completion();
+ void read_completion();
+
+private:
+ static VirtioVDIPort* _singleton;
+ HANDLE _handle;
+};
+
+// Ring notes:
+// _end is one after the end of data
+// _start==_end means empty ring
+// _start-1==_end (modulo) means full ring
+// _start-1 is never used
+// ring_write & read on right side of the ring (update _end)
+// ring_read & write from left (update _start)
+
+
+#endif //_H_VIRTIO_VDI_PORT
\ No newline at end of file |