On Tue, May 22, 2018 at 07:46:48AM -0400, Frediano Ziglio wrote: > > > > On Mon, May 21, 2018 at 11:45:29AM +0100, Frediano Ziglio wrote: > > > Check if the current display server is active or not and stream only if > > > active. > > > This will allow to support multiple display servers running. > > > When multiple display servers are running only one have the GPU > > > associated and is writing to the screen. > > > Stop capturing and release resources when the display server is not > > > active and vice versa. > > > > Is your goal to achieve something similar to > > https://cgit.freedesktop.org/spice/linux/vd_agent/commit/?id=93003ec27d98cb47b8ea0435179a66c14ff610ce > > ? > > > > Christophe > > > > I basically need to follow the active session on seat0 (the physical one, > like the physical display). > Usually GPU is attached to a single session and by the way we don't want > to stream all possible sessions active but just the one that is active. Isn't this something that logind provides rather than the apparently X specific code you are using in this patch? (see loginctl list-sessions/show-session). Christophe > > > > > > > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > > > --- > > > src/Makefile.am | 2 ++ > > > src/eventfd.cpp | 38 ++++++++++++++++++++ > > > src/eventfd.hpp | 34 ++++++++++++++++++ > > > src/spice-streaming-agent.cpp | 65 +++++++++++++++++++++++++++++++---- > > > 4 files changed, 132 insertions(+), 7 deletions(-) > > > create mode 100644 src/eventfd.cpp > > > create mode 100644 src/eventfd.hpp > > > > > > diff --git a/src/Makefile.am b/src/Makefile.am > > > index 276478f..ffc52b2 100644 > > > --- a/src/Makefile.am > > > +++ b/src/Makefile.am > > > @@ -62,4 +62,6 @@ spice_streaming_agent_SOURCES = \ > > > jpeg.hpp \ > > > stream-port.cpp \ > > > stream-port.hpp \ > > > + eventfd.cpp \ > > > + eventfd.hpp \ > > > $(NULL) > > > diff --git a/src/eventfd.cpp b/src/eventfd.cpp > > > new file mode 100644 > > > index 0000000..e3c1e72 > > > --- /dev/null > > > +++ b/src/eventfd.cpp > > > @@ -0,0 +1,38 @@ > > > +/* Linux event file descriptors > > > + * > > > + * \copyright > > > + * Copyright 2018 Red Hat Inc. All rights reserved. > > > + */ > > > +#include <config.h> > > > +#include "eventfd.hpp" > > > + > > > +#include <stdexcept> > > > +#include <sys/eventfd.h> > > > + > > > +template<typename T> > > > +inline void ignore_result(T /* unused result */) {} > > > + > > > +namespace spice { > > > +namespace streaming_agent { > > > + > > > +EventFD::EventFD(): > > > + fd(eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK)) > > > +{ > > > + if (fd < 0) { > > > + throw std::runtime_error("Failed to create eventfd"); > > > + } > > > +} > > > + > > > +void EventFD::signal() > > > +{ > > > + uint64_t n = 1; > > > + ignore_result(write(fd, &n, sizeof(n))); > > > +} > > > + > > > +void EventFD::ack() > > > +{ > > > + uint64_t n; > > > + ignore_result(read(fd, &n, sizeof(n))); > > > +} > > > + > > > +}} // namespace spice::streaming_agent > > > diff --git a/src/eventfd.hpp b/src/eventfd.hpp > > > new file mode 100644 > > > index 0000000..48a175c > > > --- /dev/null > > > +++ b/src/eventfd.hpp > > > @@ -0,0 +1,34 @@ > > > +/* Linux event file descriptors > > > + * > > > + * \copyright > > > + * Copyright 2018 Red Hat Inc. All rights reserved. > > > + */ > > > +#ifndef SPICE_STREAMING_AGENT_EVENTFD_HPP > > > +#define SPICE_STREAMING_AGENT_EVENTFD_HPP > > > + > > > +#include <unistd.h> > > > + > > > +namespace spice { > > > +namespace streaming_agent { > > > + > > > +class EventFD { > > > +public: > > > + EventFD(); > > > + ~EventFD() { close(fd); } > > > + void signal(); > > > + void ack(); > > > + /** > > > + * Returns underlying file descriptor. > > > + * Do not close, should just be used for polling. > > > + */ > > > + int raw_fd() const { return fd; } > > > +private: > > > + EventFD(const EventFD&) = delete; > > > + void operator=(const EventFD&) = delete; > > > + > > > + int fd; > > > +}; > > > + > > > +}} // namespace spice::streaming_agent > > > + > > > +#endif // SPICE_STREAMING_AGENT_EVENTFD_HPP > > > diff --git a/src/spice-streaming-agent.cpp b/src/spice-streaming-agent.cpp > > > index 6388bb2..240b9c7 100644 > > > --- a/src/spice-streaming-agent.cpp > > > +++ b/src/spice-streaming-agent.cpp > > > @@ -10,6 +10,7 @@ > > > #include "stream-port.hpp" > > > #include "error.hpp" > > > #include "xorg-utils.hpp" > > > +#include "eventfd.hpp" > > > > > > #include <spice/stream-device.h> > > > #include <spice/enums.h> > > > @@ -36,6 +37,7 @@ > > > #include <thread> > > > #include <vector> > > > #include <string> > > > +#include <atomic> > > > #include <functional> > > > #include <X11/Xlib.h> > > > #include <X11/extensions/Xfixes.h> > > > @@ -61,12 +63,21 @@ static bool quit_requested = false; > > > static bool log_binary = false; > > > static bool log_frames = false; > > > static std::set<SpiceVideoCodecType> client_codecs; > > > +static EventFD update_fd; > > > +static const char vt_property_name[] = "XFree86_has_VT"; > > > +static const char *stream_port_name = > > > "/dev/virtio-ports/org.spice-space.stream.0"; > > > +static Atom vt_property = None; > > > +static std::atomic_bool vt_active; > > > > > > -static bool have_something_to_read(StreamPort &stream_port, bool blocking) > > > +static bool have_something_to_read(StreamPort &stream_port, bool blocking, > > > int &fd) > > > { > > > - struct pollfd pollfd = {stream_port.fd, POLLIN, 0}; > > > + struct pollfd pollfds[2] = { > > > + { stream_port.fd, POLLIN, 0 }, > > > + { update_fd.raw_fd(), POLLIN, 0 }, > > > + }; > > > > > > - if (poll(&pollfd, 1, blocking ? -1 : 0) < 0) { > > > + fd = -1; > > > + if (poll(pollfds, 2, blocking ? -1 : 0) < 0) { > > > if (errno == EINTR) { > > > // report nothing to read, next iteration of the enclosing > > > loop will retry > > > return false; > > > @@ -75,7 +86,13 @@ static bool have_something_to_read(StreamPort > > > &stream_port, bool blocking) > > > throw IOError("poll failed on the device", errno); > > > } > > > > > > - if (pollfd.revents & POLLIN) { > > > + if (pollfds[1].revents & POLLIN) { > > > + fd = update_fd.raw_fd(); > > > + return true; > > > + } > > > + > > > + if (pollfds[0].revents & POLLIN) { > > > + fd = stream_port.fd; > > > return true; > > > } > > > > > > @@ -173,8 +190,18 @@ static void read_command_from_device(StreamPort > > > &stream_port) > > > static void read_command(StreamPort &stream_port, bool blocking) > > > { > > > while (!quit_requested) { > > > - if (have_something_to_read(stream_port, blocking)) { > > > - read_command_from_device(stream_port); > > > + int fd; > > > + if (have_something_to_read(stream_port, blocking, fd)) { > > > + if (fd == stream_port.fd) { > > > + read_command_from_device(stream_port); > > > + } else if (fd == update_fd.raw_fd()) { > > > + update_fd.ack(); > > > + bool vt_active = > > > ::vt_active.load(std::memory_order_relaxed); > > > + if (!vt_active) { > > > + throw std::runtime_error("VT disabled"); > > > + } > > > + continue; > > > + } > > > break; > > > } > > > > > > @@ -305,10 +332,22 @@ send_cursor(StreamPort &stream_port, unsigned width, > > > unsigned height, int hotspo > > > static void cursor_changes(StreamPort *stream_port, Display *display, int > > > event_base) > > > { > > > unsigned long last_serial = 0; > > > + Window rootwindow = DefaultRootWindow(display); > > > > > > while (1) { > > > XEvent event; > > > XNextEvent(display, &event); > > > + > > > + if (event.type == PropertyNotify) { > > > + if (vt_property == None || event.xproperty.atom != > > > vt_property) > > > + continue; > > > + // update vt property, activate screen read if needed > > > + vt_active.store(get_win_prop_int(display, rootwindow, > > > vt_property) != 0, std::memory_order_relaxed); > > > + std::atomic_thread_fence(std::memory_order_acquire); > > > + update_fd.signal(); > > > + continue; > > > + } > > > + > > > if (event.type != event_base + 1) { > > > continue; > > > } > > > @@ -416,7 +455,6 @@ do_capture(StreamPort &stream_port, FILE *f_log) > > > > > > int main(int argc, char* argv[]) > > > { > > > - const char *stream_port_name = > > > "/dev/virtio-ports/org.spice-space.stream.0"; > > > int opt; > > > const char *log_filename = NULL; > > > int logmask = LOG_UPTO(LOG_WARNING); > > > @@ -522,6 +560,19 @@ int main(int argc, char* argv[]) > > > Window rootwindow = DefaultRootWindow(display); > > > XFixesSelectCursorInput(display, rootwindow, > > > XFixesDisplayCursorNotifyMask); > > > > > > + vt_property = XInternAtom(display, vt_property_name, True); > > > + if (vt_property == None) { > > > + syslog(LOG_ERR, "VT property not found\n"); > > > + return EXIT_FAILURE; > > > + } > > > + XSelectInput(display, rootwindow, PropertyChangeMask); > > > + > > > + vt_active.store(get_win_prop_int(display, rootwindow, vt_property) != > > > 0, std::memory_order_relaxed); > > > + if (!::vt_active.load(std::memory_order_relaxed)) { > > > + syslog(LOG_ERR, "VT is disabled"); > > > + return EXIT_FAILURE; > > > + } > > > + > > > int ret = EXIT_SUCCESS; > > > > > > try { > > Frediano > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/spice-devel
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel