This introduces wl_event_queue, which is what will make multi-threaded
wayland clients possible and useful. The driving use case is that of a
GL rendering thread that renders and calls eglSwapBuffer independently of
a "main thread" that owns the wl_display and handles input events and
everything else. In general, the EGL and GL APIs have a threading model
that requires the wayland client library to be usable from several threads.
Finally, the current callback model gets into trouble even in a single
threaded scenario: if we have to block in eglSwapBuffers, we may end up
doing unrelated callbacks from within EGL.
The wl_event_queue mechanism lets the application (or middleware such as
EGL or toolkits) assign a proxy to an event queue. Only events from objects
associated with the queue will be put in the queue, and conversely,
events from objects associated with the queue will not be queue up anywhere
else. The wl_display struct has a built-in event queue, which is considered
the main and default event queue. New proxies are associated with the
same queue as the object that created them (either the object that a
request with a new-id argument was sent to or the object that sent an
event with a new-id argument). A proxy can be moved to a different event
queue by calling wl_proxy_set_queue().
A subsystem, such as EGL, will then create its own event queue and associate
the objects it expects to receive events from with that queue. If EGL
needs to block and wait for a certain event, it can keep dispatching event
from its queue until that events comes in. This wont call out to unrelated
code with an EGL lock held. Similarly, we don't risk the main thread
handling an event from an EGL object and then calling into EGL from a
different thread without the lock held.
The update callback for the file descriptors was always a bit awkward and
un-intuitive. The idea was that whenever the protocol code needed to
write data to the fd it would call the 'update' function. This function
would adjust the mainloop so that it polls for POLLOUT on the fd so we
can eventually flush the data to the socket.
The problem is that in multi-threaded applications, any thread can issue
a request, which writes data to the output buffer and thus triggers the
update callback. Thus, we'll be calling out with the display mutex
held and may call from any thread.
The solution is to eliminate the udpate callback and just require that
the application or server flushes all connection buffers before blocking.
This turns out to be a simpler API, although we now require clients to
deal with EAGAIN and non-blocking writes. It also saves a few syscalls,
since the socket will be writable most of the time and most writes will
complete, so we avoid changing epoll to poll for POLLOUT, then write and
then change it back for each write.
Attempting to write anything longer into the embedded char
array would create a non-null-terminated string, and all
later reads would run off the end into invalid memory.
This is a hard limitation of AF_LOCAL/AF_UNIX sockets.
When the server send a new object ID, the client used to have to allocate
the proxy manually and without type-safety. We now allocate the proxy
in a client-side post-processing step on the incoming closure.
The core libwayland libraries should not handle logging, only passing
the error messages to subscribed functions.
An application linked to libwayland-server or libwayland-client
will be able to set own functions (one per library) to handle error
messages.
Change in this series: make the wl_log return int, because
of compatibility with printf. It will return the number of bytes logged.
Some system C libraries do not offer SOCK_CLOEXEC flag.
Add a new header for OS compatibility wrappers. Wrap socket() calls into
wl_os_socket_cloexec() which makes sure the O_CLOEXEC flag gets set on
the file descriptor.
On systems having SOCK_CLOEXEC this uses the old socket() call, and
falls back if it fails due to the flag (kernel not supporting it).
wayland-os.h is private and not exported.
Add close-on-exec tests for both normal and forced fallback paths.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
The wayland protocol, as X, uses timestamps to match up certain
requests with input events. The problem is that sometimes we need to
send out an event that doesn't have a corresponding timestamped input
event. For example, the pointer focus surface goes away and new
surface needs to receive a pointer enter event. These events are
normally timestamped with the evdev event timestamp, but in this case,
we don't have a evdev timestamp. So we have to go to gettimeofday (or
clock_gettime()) and then we don't know if it's coming from the same
time source etc.
However for all these cases we don't need a real time timestamp, we
just need a serial number that encodes the order of events inside the
server. So we introduce a serial number mechanism that we can use to
order events. We still need real-time timestamps for actual input
device events (motion, buttons, keys, touch), to be able to reason
about double-click speed and movement speed so events that correspond to user input carry both a serial number and a timestamp.
The serial number also give us a mechanism to key together events that
are "logically the same" such as a unicode event and a keycode event,
or a motion event and a relative event from a raw device.
In case the client isn't responding, this will block the compositor.
Instead we flush with MSG_DONTWAIT, which lets us fill up the kernel buffer
as much as we can (after not returning EPOLLOUT anymore it still can take
80k more), and then disconnect the client if we get EAGAIN.
Ignore previous patch, here's the correct version.
From 4e1bedaaf05b576f5191f8fe3a34904ab9707414 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <samuel.rodal@nokia.com>
Date: Mon, 27 Feb 2012 15:17:20 +0100
Subject: [PATCH] Allow update function to not be set in wl_display_get_fd
The same check is done in connection_update, and now with
wl_display_flush() there's less need for the client to need to know the
connection mask.
This avoids the clash with the wayland-server version with the same
name, and allows linking against both wayland-client and wayland-server
at the same time, which can be useful for unit testing purposes as
well as for nested compositing.
Without this there will be crashes as the wrong wl_display_destroy()
is called.
Memory leak found by valgrinding simple-shm client.
struct wl_global::interface is a strdup()'d string that was never freed.
Make a function for freeing a wl_global, and use it.
krh: Edit to name wl_global destructor wl_global_destroy.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
WAYLAND_SOCKET contains a file descriptor that is an open connection to
a Wayland server. It is private to us, and makes no sense to relay the
same value (or any value) to our child processes.
Unset the environment variable to prevent it from being accidentally
relayed to other processes.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit brings a big change to the DND and copy/paste interfaces.
Most importantly the functionality is now independent of wl_shell.
The wl_shell interface is intended for desktop style UI interaction and
an optional and experimental interface.
The new interface also allows receiving the DND data multiple times or
multiple times during the drag, and the mechanism for offering and receiving
data is now shared between DND and selections.
We set aside a range of the object ID space for use by the server. This
allows the server to bind an object to an ID for a client and pass that
object to the client. The client can use the object immediately and the
server can emit events to the object immdiately.
Some events, such as the display.delete_id, aren't very urgent and we
would like to not always send them immdiately and cause an unnecessary
context switch. The wl_resource_queue_event() function will place the
event in the connection output buffer but not request the main loop to
poll for writable. The effect is that the event will just sit in the
output buffer until a more important event comes around and requires
flushing.
We need to make sure the client doesn't reuse an object ID until the
server has seen the destroy request. When a client destroys an ID
the server will now respond with the display.delete_id event, which lets
the client block reuse until it receives the event.
So obvious in retrospect. The object system can do all the work for us
and keep track of pending calls as regular objects and we don't need to
abuse the resource system to get them cleaned up on client exit. We
don't need the custom key management or (broken) lookup, we just sue
object IDs. And last but not least, anybody can receive the callback,
not just display listeners.