octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Thread-safe access to graphic objects - proposal


From: Maciej Gajewski
Subject: Thread-safe access to graphic objects - proposal
Date: Thu, 3 Jul 2008 12:22:58 +0200

Hello everyone

This is proposal of locking scheme for graphics object, making them
safe to access from multiple threads.

Rationale
========

This is a snippet from discussion about Qt-based plotting/UI backend
I'm currently working on:

> > 3. In response for backend calls (close_figure, redraw_figure, print), send
> > appropriate message to GUI thread, also copy object properties (syncing
> > threads), so they can be safely accessed by GUI code from GUI thread.
>
> I used to do something similar in JHandles, but eventually dropped the
> idea for efficiency (copying all props takes time) and maintenance
> (keeping 2 property sets in sync, property addition...) reasons. The
> main problem is then to avoid race conditions. I proposed a locking
> scheme a few months ago on this mailing list, but we didn't really
> reach an agreement. But I hope that in the future, octave will provide
> a mechanism to access graphics object properties in a thread-safe
> way, without having to duplicate all properties.

As Michael Goffioul points, copying all properties from main thread to
GUI thread, and then sending all properties changed by GUI back to
main thread is hell.
While just copying them one-way would be not so bad, sending changes
back from GUI and synchronizing requires complicated and
hard-to-maintain facilities.

And GUI changes its properties pretty often: each time figure window
is moved or resized, it's properties should change. Then: axes are
zoomed, rotated, annotation can be added etc etc.

This all could be made simple bu just adding locks in appropriate
places in graphics.h /graphics.cc. Having thread-safe property access
could allow GUI backend to simply read and modify it's properties at
any time.

Proposed implementation
======================

1. Use boost libraries. they are beautifully designed, crossplatform,
plays well with std and are widely available.
2. Add one central mutex to gh_manager instance.
3a. Add lock() / lock_shared() / unlock() / unlock_shared() to gh_manager, or
3b. simply leave the mutex exposed, so anyone can lock/unlock it, or
use locker object to get simple RAII locking.
4. Add appropriate locks/unlocks in graphics.cc, in places where:
 * properties are modified,
 * new objects are created,
 * objects are destroyed,
 * properties are read.

Then - backend living in another thread could use the same locking
mechanism to access/modify properties.

Another idea is to lock in every property set/get method, but this
would exclude case where objects are destroyed, possibly leaving GUI
thread with dangling pointer. So IMO entire blocks of code obtaining
object pointer from handle, then properties from object, then
reading/manipulating them.

Using boost RAII classes this could be pretty simple:

void backend::readprops()
{
  shared_lock lock( gh_manager::get_mutex() ); // this obtains lock.
For modification, use unique_lock instead.

  // this is actual part of code from fltk and qt backend
  graphics_object fobj = gh_manager::get_object (fh);
  if (fobj &&  fobj.isa ("figure") )
  {
    // get properties
    figure::properties& fp = dynamic_cast<figure::properties&>(
fobj.get_properties() );

    // read properties here... (or modify, if unique_lock used)
  }
} // here the lock dies, releasing mutex

I volunteer to implement this, but I would need help adding
appropriate checks/dependencies into build system.

RFC

Maciek Gajewski


reply via email to

[Prev in Thread] Current Thread [Next in Thread]