summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2013-11-14 12:28:51 +0000
committerKristian Høgsberg <krh@bitplanet.net>2013-11-15 14:46:48 -0800
commitc2bba88ccd68c5ea6792a875499cec276db594f8 (patch)
tree9cb17ee682b03c0d05826771f44f0ad36ff05af1
parenta71cf48ce0d92d891461fd2a2da05860b418dcee (diff)
Add documentation for wl_shm_buffer_begin/end_access
It's not obvious that these functions are needed so it would be good to have some documentation for them.
-rw-r--r--doc/doxygen/Makefile.am3
-rw-r--r--src/wayland-shm.c64
2 files changed, 66 insertions, 1 deletions
diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am
index 0351c1e..078506d 100644
--- a/doc/doxygen/Makefile.am
+++ b/doc/doxygen/Makefile.am
@@ -14,7 +14,8 @@ scanned_src_files_client = \
scanned_src_files_server = \
$(scanned_src_files_shared) \
$(top_srcdir)/src/wayland-server.c \
- $(top_srcdir)/src/wayland-server.h
+ $(top_srcdir)/src/wayland-server.h \
+ $(top_srcdir)/src/wayland-shm.c
# find all man/man3/wl_foo.3 pages
# for this to work, we need to create them before the man target (hence
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 28f52f4..814a4cf 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -358,6 +358,23 @@ wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer)
return buffer->stride;
}
+
+/** Get a pointer to the memory for the SHM buffer
+ *
+ * \param buffer The buffer object
+ *
+ * Returns a pointer which can be used to read the data contained in
+ * the given SHM buffer.
+ *
+ * As this buffer is memory-mapped, reading it from may generate
+ * SIGBUS signals. This can happen if the client claims that the
+ * buffer is larger than it is or if something truncates the
+ * underlying file. To prevent this signal from causing the compositor
+ * to crash you should call wl_shm_buffer_begin_access and
+ * wl_shm_buffer_end_access around code that reads from the memory.
+ *
+ * \memberof wl_shm_buffer
+ */
WL_EXPORT void *
wl_shm_buffer_get_data(struct wl_shm_buffer *buffer)
{
@@ -454,6 +471,42 @@ init_sigbus_data_key(void)
pthread_key_create(&wl_shm_sigbus_data_key, destroy_sigbus_data);
}
+/** Mark that the given SHM buffer is about to be accessed
+ *
+ * \param buffer The SHM buffer
+ *
+ * An SHM buffer is a memory-mapped file given by the client.
+ * According to POSIX, reading from a memory-mapped region that
+ * extends off the end of the file will cause a SIGBUS signal to be
+ * generated. Normally this would cause the compositor to terminate.
+ * In order to make the compositor robust against clients that change
+ * the size of the underlying file or lie about its size, you should
+ * protect access to the buffer by calling this function before
+ * reading from the memory and call wl_shm_buffer_end_access
+ * afterwards. This will install a signal handler for SIGBUS which
+ * will prevent the compositor from crashing.
+ *
+ * After calling this function the signal handler will remain
+ * installed for the lifetime of the compositor process. Note that
+ * this function will not work properly if the compositor is also
+ * installing its own handler for SIGBUS.
+ *
+ * If a SIGBUS signal is received for an address within the range of
+ * the SHM pool of the given buffer then the client will be sent an
+ * error event when wl_shm_buffer_end_access is called. If the signal
+ * is for an address outside that range then the signal handler will
+ * reraise the signal which would will likely cause the compositor to
+ * terminate.
+ *
+ * It is safe to nest calls to these functions as long as the nested
+ * calls are all accessing the same buffer. The number of calls to
+ * wl_shm_buffer_end_access must match the number of calls to
+ * wl_shm_buffer_begin_access. These functions are thread-safe and it
+ * is allowed to simultaneously access different buffers or the same
+ * buffer from multiple threads.
+ *
+ * \memberof wl_shm_buffer
+ */
WL_EXPORT void
wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer)
{
@@ -480,6 +533,17 @@ wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer)
sigbus_data->access_count++;
}
+/** Ends the access to a buffer started by wl_shm_buffer_begin_access
+ *
+ * \param buffer The SHM buffer
+ *
+ * This should be called after wl_shm_buffer_begin_access once the
+ * buffer is no longer being accessed. If a SIGBUS signal was
+ * generated in-between these two calls then the resource for the
+ * given buffer will be sent an error.
+ *
+ * \memberof wl_shm_buffer
+ */
WL_EXPORT void
wl_shm_buffer_end_access(struct wl_shm_buffer *buffer)
{