On Sun, Jan 02, 2011 at 01:33:55PM +0200, Arnon Gilboa wrote: > Alon Levy wrote: > >introduce VDIPort::get_num_events and VDIPort::fill_events, > >change VDService::_events to be dynamically allocated > >document _events contents: STATIC events, then vdi_port, then agent. > >--- > > vdservice/vdi_port.cpp | 2 +- > > vdservice/vdi_port.h | 17 +++++++-- > > vdservice/vdservice.cpp | 83 > > +++++++++++++++++++++++++++++----------------- > > 3 files changed, 66 insertions(+), 36 deletions(-) > > > >diff --git a/vdservice/vdi_port.cpp b/vdservice/vdi_port.cpp > >index e36ff86..f4dfaeb 100644 > >--- a/vdservice/vdi_port.cpp > >+++ b/vdservice/vdi_port.cpp > >@@ -56,7 +56,7 @@ bool VDIPort::init() > > _handle = CreateFile(VIOSERIAL_PORT_PATH, GENERIC_READ | GENERIC_WRITE > > , 0, NULL, > > OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); > > if (_handle == INVALID_HANDLE_VALUE) { > >- vd_printf("CreateFile() failed: %u", GetLastError()); > >+ vd_printf("CreateFile() %s failed: %u", VIOSERIAL_PORT_PATH, > >GetLastError()); > > return false; > > } > > _write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); > >diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h > >index a10b346..8e057bb 100644 > >--- a/vdservice/vdi_port.h > >+++ b/vdservice/vdi_port.h > >@@ -46,14 +46,23 @@ public: > > size_t ring_read(void* buf, size_t size); > > size_t read_ring_size(); > > size_t read_ring_continuous_remaining_size(); > >- HANDLE get_write_event() { return _write.overlap.hEvent; } > >- HANDLE get_read_event() { return _read.overlap.hEvent; } > >+ unsigned get_num_events() { return 2; } > >+ void fill_events(HANDLE *handle) { > >+ handle[0] = _write.overlap.hEvent; > >+ handle[1] = _read.overlap.hEvent; > >+ } > >+ void handle_event(int event) { > >+ switch (event) { > >+ case 0: write_completion(); break; > >+ case 1: read_completion(); break; > >+ } > >+ } > not 1-liners, so will be nicer in the cpp ok.
> consider using #defines ok. > HANDLE *handle -> HANDLE* handles ok. > > int write(); > > int read(); > >- void write_completion(); > >- void read_completion(); > > private: > >+ void write_completion(); > >+ void read_completion(); > > int handle_error(); > > private: > >diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp > >index ae5ad87..72882ea 100644 > >--- a/vdservice/vdservice.cpp > >+++ b/vdservice/vdservice.cpp > >@@ -40,15 +40,19 @@ > > #define CREATE_PROC_MAX_RETRIES 10 > > #define CREATE_PROC_INTERVAL_MS 500 > >+// This enum simplifies WaitForMultipleEvents for static > >+// events, that is handles that are guranteed non NULL. > >+// It doesn't include: > >+// VDIPort Handles - these are filled by an interface because > >+// of variable handle number. > >+// VDAgent handle - this can be 1 or 0 (NULL or not), so it is also added at > >+// the end of VDService::_events > > enum { > > VD_EVENT_PIPE_READ = 0, > > VD_EVENT_PIPE_WRITE, > > VD_EVENT_CONTROL, > >- VD_EVENT_READ, > >- VD_EVENT_WRITE, > > VD_EVENT_LOGON, > >- VD_EVENT_AGENT, // Must be before last > >- VD_EVENTS_COUNT // Must be last > >+ VD_STATIC_EVENTS_COUNT // Must be last > > }; > nice > > class VDService { > >@@ -76,7 +80,15 @@ private: > > bool launch_agent(); > > void send_logon(); > > bool kill_agent(); > >- > >+ unsigned fill_agent_event() { > >+ ASSERT(_events); > >+ if (_agent_proc_info.hProcess) { > >+ _events[_events_count - 1] = _agent_proc_info.hProcess; > >+ return _events_count; > >+ } else { > >+ return _events_count - 1; > >+ } > >+ } > like above, will be nicer in the cpp > > private: > > static VDService* _singleton; > > SERVICE_STATUS _status; > >@@ -84,7 +96,7 @@ private: > > PROCESS_INFORMATION _agent_proc_info; > > HANDLE _control_event; > > HANDLE _logon_event; > >_pending_write > >- HANDLE _events[VD_EVENTS_COUNT]; > >+ HANDLE* _events; > > TCHAR _agent_path[MAX_PATH]; > > VDIPort* _vdi_port; > > VDPipeState _pipe_state; > >@@ -103,6 +115,8 @@ private: > > bool _agent_alive; > > bool _running; > > VDLog* _log; > >+ unsigned _events_count; > >+ unsigned _events_vdi_port_base; > > }; > > VDService* VDService::_singleton = NULL; > >@@ -142,6 +156,7 @@ int supported_system_version() > > VDService::VDService() > > : _status_handle (0) > >+ , _events (NULL) > > , _vdi_port (NULL) > > , _connection_id (0) > > , _session_id (0) > >@@ -156,10 +171,11 @@ VDService::VDService() > > , _agent_alive (false) > > , _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)); > >- ZeroMemory(_events, sizeof(_events)); > > _system_version = supported_system_version(); > > _control_event = CreateEvent(NULL, FALSE, FALSE, NULL); > > _pipe_state.write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, > > NULL); > >@@ -176,6 +192,7 @@ VDService::~VDService() > > CloseHandle(_pipe_state.read.overlap.hEvent); > > CloseHandle(_pipe_state.write.overlap.hEvent); > > CloseHandle(_control_event); > >+ delete _events; > > delete _log; > > } > >@@ -423,14 +440,19 @@ bool VDService::execute() > > CloseHandle(pipe); > > return false; > > } > >+ _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; > >- _events[VD_EVENT_READ] = _vdi_port->get_read_event(); > >- _events[VD_EVENT_WRITE] = _vdi_port->get_write_event(); > > _events[VD_EVENT_LOGON] = _logon_event; > >- _events[VD_EVENT_AGENT] = _agent_proc_info.hProcess; > >+ _agent_proc_info.hProcess; > >+ vd_printf("Calling fill_events"); > >+ vd_printf("&_events[VD_ENVETS_COUNT] == %p", > >&_events[VD_STATIC_EVENTS_COUNT]); > i guess these logs are later removed ;) > >+ _vdi_port->fill_events(&_events[_events_vdi_port_base]); > > _chunk_size = _chunk_port = 0; > > read_pipe(); > > while (_running) { > >@@ -456,8 +478,8 @@ bool VDService::execute() > > handle_pipe_data(0); > > } > > if (_running && (!cont || _pending_read || _pending_write)) { > >- DWORD events_count = _events[VD_EVENT_AGENT] ? VD_EVENTS_COUNT > >: VD_EVENTS_COUNT - 1; > >- DWORD wait_ret = WaitForMultipleObjects(events_count, _events, > >FALSE, > >+ unsigned actual_events = fill_agent_event(); > why is fill_agent_event() called in each iteration? is it for cases > agent is already down? Yes. Or up - the agent state can change between each iteration, so we refill the _events array, that's what fill_agent_event does, and it returns the number of total events. > >+ DWORD wait_ret = WaitForMultipleObjects(actual_events, _events, > >FALSE, > > cont ? 0 : > > INFINITE); > > switch (wait_ret) { > > case WAIT_OBJECT_0 + VD_EVENT_PIPE_READ: { > >@@ -482,28 +504,29 @@ bool VDService::execute() > > case WAIT_OBJECT_0 + VD_EVENT_CONTROL: > > vd_printf("Control event"); > > break; > >- case WAIT_OBJECT_0 + VD_EVENT_READ: > >- _vdi_port->read_completion(); > >- break; > >- case WAIT_OBJECT_0 + VD_EVENT_WRITE: > >- _vdi_port->write_completion(); > >- break; > > case WAIT_OBJECT_0 + VD_EVENT_LOGON: > > vd_printf("logon event"); > > write_agent_control(VD_AGENT_SESSION_LOGON, 0); > > break; > >- case WAIT_OBJECT_0 + VD_EVENT_AGENT: > >- vd_printf("Agent killed"); > >- if (_system_version == SYS_VER_WIN_XP) { > >- restart_agent(false); > >- } else if (_system_version == SYS_VER_WIN_7) { > >- kill_agent(); > >- } > >- break; > > case WAIT_TIMEOUT: > > break; > > default: > >- vd_printf("WaitForMultipleObjects failed %u", > >GetLastError()); > >+ if (wait_ret == WAIT_OBJECT_0 + _events_count - 1) { > >+ vd_printf("Agent killed"); > >+ if (_system_version == SYS_VER_WIN_XP) { > >+ restart_agent(false); > >+ } else if (_system_version == SYS_VER_WIN_7) { > >+ kill_agent(); > >+ } > >+ } else { > following if-else should be part of the above 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); > >+ } else { > >+ vd_printf("WaitForMultipleObjects failed %u", > >GetLastError()); > >+ } > >+ } > > } > > } > > } > >@@ -802,7 +825,6 @@ bool VDService::launch_agent() > > vd_printf("ConnectNamedPipe() failed: %u", GetLastError()); > > return false; > > } > >- _events[VD_EVENT_AGENT] = _agent_proc_info.hProcess; > > return true; > > } > >@@ -815,7 +837,6 @@ bool VDService::kill_agent() > > if (!_agent_alive) { > > return true; > > } > >- _events[VD_EVENT_AGENT] = 0; > > _agent_alive = false; > > if (_pipe_connected) { > > _pipe_connected = false; > >@@ -909,8 +930,8 @@ void VDService::pipe_write_completion() > > } else { > > vd_printf("GetOverlappedResult() failed : %d", GetLastError()); > > } > >- _pending_write = false; > >- } > >+ _pending_write = false; > >+ } > > if (ps->write.start < ps->write.end) { > > _pending_write = true; > _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel