<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2016-07-05 23:30 GMT+02:00 Shawn Waldon <span dir="ltr"><<a href="mailto:shawn.waldon@kitware.com" target="_blank">shawn.waldon@kitware.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>Hi Elvis,<br><br></div>I've done something fairly similar in one of my applications, returning a vtkSmartPointer<vtkImageData> via a Qt signal/slot from a background thread.  And as far as I know the reference counting should work fine since the reference count is an atomic integer.  It has worked fine for me so far and VTK_DEBUG_LEAKS doesn't complain so the reference counts are working somehow.<br><br>My guess about your reference count question:  You are returning the smart pointer by value.  The QFuture must be storing the smart pointer so that it can return it from the result() function.  And when you return it that way it creates a second smart pointer, which would increment the reference count to 2.<br></div></div></blockquote><div><br></div><div>Ah, of course. Thanks! So then it's not a problem, my QFuture will be destroyed shortly thereafter as well.<br><br></div><div>And thanks for also bringing up VTK_DEBUG_LEAKS, I didn't know about.<br><br></div><div>But, so I can assume that both approaches (raw pointer, return a shallow copy) and returning a vtkSmartPointer are safe ways of doing this in this case? Nothing in the VTK ref counting machinery that could go wrong?<br><br></div><div>Do you know if there are any things/gotchas or parts of VTK to watch out for when putting parts of a pipeline in a separate thread like this?<br><br></div><div>Elvis<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>HTH,<br></div>Shawn<br></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Tue, Jul 5, 2016 at 5:11 PM, Elvis Stansvik <span dir="ltr"><<a href="mailto:elvis.stansvik@orexplore.com" target="_blank">elvis.stansvik@orexplore.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><div><div>Just as I was going to ask a threading question on this list, someone else did :) Oh well here's another one:<br><br></div>I'm rendering a compressed volume, and I've noticed that a big chunk of the time-to-first-render for me is the initial reading of the volume. To keep the UI responsive while the reading takes place, I decided to give QtConcurrent::run + QFuture + QFutureWatcher a try as a mechanism to put the reading in a different thread.<br><br></div>Here's a shortened version of what I did:<br><div><br>    auto future = QtConcurrent::run([&]() -> vtkImageData * {<br>        auto reader = vtkSmartPointer<HDF5ImageReader>::New();<br>        reader->setFileName("big_compressed_volume.hdf5");<br>        reader->Update();<br><br>        auto output = reader->GetOutput();<br>        auto result = output->NewInstance();<br>        result->ShallowCopy(output);<br><br>        return result;<br>    });<br><br>    auto futureWatcher = new QFutureWatcher<vtkImageData *>(this);<br><br>    connect(futureWatcher, &QFutureWatcher<vtkImageData *>::finished, [=]() {<br>        auto imageData = futureWatcher->result();<br><br></div><div>        // ... Create the rendering part of the pipeline<br><br>        GetRenderWindow()->Render();<br>    });<br><br>    futureWatcher->setFuture(future);<br><br></div><div>This works great. Using QtConcurrent::run, I spin up a thread in which the reading takes place. When the resulting vtkImageData is ready, I return a shallow copy of it, which in turn causes the QFutureWatcher I set up to emit the finished signal, upon which I construct the remaining (rendering) part of the pipeline (which doesn't take much time compared to the reading, about ~1/6 of the time).<br></div><div><br>Now to my questions:<br><br>1. Is this safe? Since the reader is destroyed by the time the rest of the pipeline takes over (courtesy of using Qt signal delivery as a synchronization point), there's no risk of concurrent access to VTK objects here, right?<br><br></div><div>2. Can I always use this approach for segments of my pipeline up until the rendering parts (up to the mapper?), or are there non-rendering parts of VTK which simply cannot run in a separate thread?<br></div><div><br>3. Regarding the shallow copying, I first tried to return just<br><br>        return vtkSmartPointer<vtkImageData>(reader->GetOutput());<br><br></div><div>from the reader function. My thinking with this was that<br><br>   * I create a smart pointer, which should raise the ref count of the object to 2, since the reader itself is still alive at that point and also holds a reference,<br>   * a copy is then made of the smart pointer (for the return value of the function), raising the refcount to 3,<br></div><div>   * when the function finally returns, the vtkSmartPointer I created, as well as the vtkSmartPointer holding the reader goes out of scope and destructs, which means the ref count goes down to 1.<br><br></div><div>But that's not what happens, I had a look at the ref count of the image data I finally got in my slot (from futureWatcher->result()), and it was 2, not 1 like I expected.<br><br></div><div>I'm obviously misunderstanding something here, anyone care to enlighten me? Does the ref counting mechanism not work across thread boundaries?<br><br></div><div>Many thanks in advance,<br><br></div><div>Elvis</div></div>
<br></div></div>_______________________________________________<br>
Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
<br>
Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" rel="noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://public.kitware.com/mailman/listinfo/vtkusers" rel="noreferrer" target="_blank">http://public.kitware.com/mailman/listinfo/vtkusers</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div></div>