--- vdservice/vdi_port.cpp | 76 +++++++++++++++++++++++++++++++++++++++ vdservice/vdi_port.h | 57 ++++++------------------------ vdservice/vdservice.cpp | 4 +-- vdservice/virtio_vdi_port.cpp | 78 ++-------------------------------------- vdservice/virtio_vdi_port.h | 44 +++++++++++++++++++++++ 5 files changed, 136 insertions(+), 123 deletions(-) create mode 100644 vdservice/vdi_port.cpp create mode 100644 vdservice/virtio_vdi_port.h
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 -- 1.7.3.4 _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel