summaryrefslogtreecommitdiff
path: root/doc/bugs/locking_fun.mdwn
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: