Proposal: Replace QSem, QSemN, SampleVar in base

Simon Marlow marlowsd at gmail.com
Wed Apr 13 21:24:19 CEST 2011


On 12/04/11 14:48, Chris Kuklewicz wrote:
> This is my first proposal to change some things in "base" and I trust
> that my request is not going to be perfect.
>
> The packages that I am proposing to change are all in Control.Concurrent
> and build on MVars: QSem, QSemN, and SampleVar.  I wish to change them
> because this will fix an important bug they have in common.  Who needs
> to approve of the following proposed change?
>
> Additional URLS:
> http://hackage.haskell.org/trac/ghc/ticket/3160
> http://hackage.haskell.org/package/SafeSemaphore
> http://haskell.org/haskellwiki/SafeConcurrent
>
> All three of QSem, QSemN, and SampleVar create an abstraction and
> attempt to maintain an invariant or behavior.  QSem and QSemN present
> the abstraction of a conserved quantity.  SampleVar wishes to maintain a
> single updatable value.
>
> All three have in common that waiting on a semaphore or read the sample
> var will block if there is no quantity or value present.  There can be
> many thread blocked in this way.
>
> All three abstractions fail to maintain their integrity in the case
> where one of the blocked waiters gets interrupted.  This is not a random
> or rare failure, they abstraction always fails after the first waiter
> dies.  Thus the root cause of the problem is that these modules were
> written with the unenforced and undocumented assumption that none of the
> waiters can be interrupted.
>
> The specific failure with QSem and QSemN is that signaling the semaphore
> will pass quantity to the already interrupted waiter.  This quantity
> leak cannot be prevented by the user of module with clever exception
> handling.  This leak will likely cause some or all future attempts to
> wait on the semaphore to block indefinitely.
>
> The specific failure with SampleVar is that writeSampleVar and
> emptySampleVar will trust the no longer correct count of blocked
> readers.  These methods can then block indefinitely.  This is triggered
> by: newEmptySampleVar, readSampleVar, kill the blocked reader,
> writeSampleVar, writeSampleVar.  The writeSampleVar should never more
> than momentarily block, so this indefinite block turns the SampleVar
> into acting like a regular MVar.  Also, isEmptySampleVar will no longer
> ever read full once the SampleVar is broken.
>
> All of these three modules can be replaced with MSem, MSemN, and
> MSampleVar in the SafeSemaphore package (on hackage).  These allow the
> same operations as those in base but without the above flaw.  If a
> waiter dies in the new modules then the waiter will have had no effect
> on the quantity or value.  Slightly surprisingly, these improved modules
> all have simpler implementations.  I have also expanded the APIs to
> expose additional useful operations that can be performed.  Finally, I
> have changed the names in the new modules to be less verbose as the
> community style has evolved to use qualified imports.
>
> There is a vanishingly small change someone depends on the flawed
> behavior of the base modules.  I propose to ignore this possibility and
> replace the old modules with thin layers around SafeSemaphore.

I don't think there's any need to introduce new types.  Just fix the 
exception safety in the existing implementations.  Could you make a patch?

Cheers,
	Simon



More information about the Libraries mailing list