Mir

Merge lp://qastaging/~afrantzis/mir/fix-1391488-basic-thread-pool-race into lp://qastaging/mir

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 2086
Proposed branch: lp://qastaging/~afrantzis/mir/fix-1391488-basic-thread-pool-race
Merge into: lp://qastaging/mir
Diff against target: 97 lines (+43/-6)
1 file modified
src/server/thread/basic_thread_pool.cpp (+43/-6)
To merge this branch: bzr merge lp://qastaging/~afrantzis/mir/fix-1391488-basic-thread-pool-race
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Alberto Aguirre (community) Approve
Alan Griffiths Approve
Review via email: mp+242348@code.qastaging.launchpad.net

Commit message

server: Fix race in BasicThreadPool

Ensure a task is removed from the task queue before notifying that the task is
done. Otherwise, scheduling new tasks based on these notifications may cause
unnecessary threads to be created.

Description of the change

server: Fix race in BasicThreadPool

Ensure a task is removed from the task queue before notifying that the task is
done. Otherwise, scheduling new tasks based on these notifications may cause
unnecessary threads to be created.

This MP replaces std::packaged_task<> with a custom Task class that provides separate operations for task execution and notifications.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

52 + auto task = std::move(tasks.front());
53 lock.unlock();
54 - task();
55 + task.execute();
56 lock.lock();
57 tasks.pop_front();

Is it really safe to unlock between the "std::move(tasks.front());" and the "tasks.pop_front();"?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> Is it really safe to unlock between the "std::move(tasks.front());" and the "tasks.pop_front();"?

It is: Worker::operator()() is the only place we manipulate tasks.front(), and it's only invoked once (as a thread functor). tasks.push_back() can't affect the validity of our front task, since we are moving from it. It was fine before too when we were taking a reference, since we are using a deque.

Actually, we can still keep using a reference by moving task.notify_done() before tasks.pop_front() (it makes no difference since we are under lock at that point).

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Unrelated CI failure: java.io.IOException: Failed to mkdirs: /var/lib/jenkins/workspace/mir-vivid-amd64-ci

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

In that case, go for it. (Maybe a comment could avoid the question in future - unless I'm alone in not grokking it first time.)

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

+1

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches