diff options
author | Neil Roberts <neil@linux.intel.com> | 2013-11-14 12:28:51 +0000 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-11-15 14:46:48 -0800 |
commit | c2bba88ccd68c5ea6792a875499cec276db594f8 (patch) | |
tree | 9cb17ee682b03c0d05826771f44f0ad36ff05af1 | |
parent | a71cf48ce0d92d891461fd2a2da05860b418dcee (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.am | 3 | ||||
-rw-r--r-- | src/wayland-shm.c | 64 |
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) { |