blob: 5ecf9f846f17ea9015c765279d5ff15958aa6018 (
plain)
It's possible for concurrent web edits to race and the winner commits both
changes at once with its commit message (see r2779). The loser gets a
message that there were conflicts and gets to see his own edits as the
conflicting edits he's supposed to resolve.
This can happen because CGI.pm writes the change, then drops the main wiki
lock before calling rcs_commit. It can't keep the lock because the commit
hook needs to be able to lock.
We batted this around for an hour or two on irc. The best solution seems to
be adding a subsidiary second lock, which is only used to lock the working
copy and is a blocking read/write lock.
- As before, the CGI will take the main wiki lock when starting up.
- Before writing to the WC, the CGI takes an exclusive lock on the WC.
- After writing to the WC, the CGI can downgrade it to a shared lock.
(This downgrade has to happen atomically, to prevent other CGIs from
stealing the exclusive lock.)
- Then the CGI, as before, drops the main wiki lock to prevent deadlock. It
keeps its shared WC lock.
- The commit hook takes first the main wiki lock and then the shared WC lock
when starting up, and holds them until it's done.
- Once the commit is done, the CGI, as before, does not attempt to regain
the main wiki lock (that could deadlock). It does its final stuff and
exits, dropping the shared WC lock.
Sample patch, with stub functions for the new lock:
|