Skip to content

Progressbar fix quiet#1703

Merged
jdtournier merged 5 commits intodevfrom
progressbar_fix_quiet
Oct 9, 2019
Merged

Progressbar fix quiet#1703
jdtournier merged 5 commits intodevfrom
progressbar_fix_quiet

Conversation

@jdtournier
Copy link
Copy Markdown
Member

Closes #1700

I think this should do it.... The first commit here is the actual fix (silly mistake on my part). The second commit cleans up the implementation a bit (better encapsulation, but really mostly cosmetic). The last commit actively prevents a ProgressBar from displaying if another is already active - which should mean there is no need to use a loglevel latch to keep nested ProgressBars quiet...

@jdtournier jdtournier added the bug label Sep 3, 2019
@jdtournier jdtournier added this to the MRtrix3 3.0 release milestone Sep 3, 2019
@jdtournier jdtournier requested a review from a team September 3, 2019 22:06
@jdtournier jdtournier self-assigned this Sep 3, 2019
@Lestropie
Copy link
Copy Markdown
Member

946f1ce echoes discussion in #263. Historically a static bool would not have been adequate; I couldn't even get the appropriate behaviour using a std::atomic_flag due to the race condition involved. But perhaps after #1586 it's only within-thread nested ProgressBars that may remain an issue. I'll see if I can find the test command I wrote at the time.

@maxpietsch
Copy link
Copy Markdown
Member

Fixes the -quiet and loglevel latch issues in mrregister.

@jdtournier
Copy link
Copy Markdown
Member Author

Historically a static bool would not have been adequate; I couldn't even get the appropriate behaviour using a std::atomic_flag due to the race condition involved.

OK, I guess there's quite a few edge cases to consider here. I'd only considered the case of nested ProgressBars, or at least ProgressBars instantiated sequentially within a single thread. The current safeguard should cater for most cases since even in a multi-threading context, the classes handling the tasks are instantiated within the main thread prior to launching the worker threads, so as long as things happen in the right order, the first to claim the ProgressBar gets to display it.

I should also point out that the LogLevel latch is still effective in silencing unwanted progress messages if required, so that's always an option.

Where things might fall over is in a context where the top-level multi-threaded operation does not itself instantiate a ProgressBar at all, but invokes multiple tasks that do instantiate their own ProgressBar. In that case, the terminal won't have been claimed first, and we end up with a race condition to claim it. But even in theory, if this was to work we would end up with multiple threads each competing to update the terminal with presumably the same progress message and different percentages - which I reckon is a situation we should be avoiding.

One additional safeguard we could put in there is to add a check at this line to ensure that the thread ID is that of the main thread. We'd have the original main thread ID stored in a global static variable within the App::init() call, and then simply check that std::this_thread::get_id() == ::MR::App::main_thread_ID when setting the show variable. This would effectively prevent any ProgressBar instantiated outside the main thread from displaying anything or interfering with another ProgressBar. This might prove a bit too restrictive, but I'm not sure, I can't think of instances where a ProgressBar that we actively want to show is instantiated outside the main thread. But I reckon it might prove effective in dealing with any edge cases: it's automatically thread-safe (regardless of any potential race conditions on the progressbar_active bool variable I've just introduced), would immediately silence any unwanted progressbars in separate threads, and probably not require any modifications to existing code. The only worry I have is with Thread::Queues where the source or sink instantiates the progressbar within its execute() call, rather than declaring the progressbar as a member. Worth considering...?

@jdtournier
Copy link
Copy Markdown
Member Author

I suggest we merge this PR to ensure more or less correct behaviour on dev, and carry on discussing the issue of how to better manage claiming the terminal in a multi-threaded context in #263 (it's still open...). Things should work fine at the moment since any instance where this would otherwise be problematic is currently dealt with using the LogLevel latch approach - what we're talking about beyond that is coming up with a strategy that won't requite such explicit handling, and that can wait...

@jdtournier
Copy link
Copy Markdown
Member Author

That last commit fixes issues that @maxpietsch pointed out to me. Should be good now...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants