Skip to content

Commit

Permalink
Fix deadlock of CharsetRangeSpec
Browse files Browse the repository at this point in the history
* `genCharsetRangeNoQuality` -> `arbitraryCharset.arbitrary`
* `arbitraryCharset.arbitrary` -> `arbitraryNioCharset`

Each needs the lock of the other.  This is a "non-circular dependency"
as described in SIP-20.

A better solution based on defs or vals will be designed for 0.16.
This is a binary-compatible mitigation for 0.15.

Fixes http4s/http4s#774
  • Loading branch information
rossabaker committed Mar 4, 2017
1 parent 54b8436 commit 0a60cb2
Showing 1 changed file with 7 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ trait ArbitraryInstances {

implicit lazy val arbitraryCharsetRange: Arbitrary[CharsetRange] =
Arbitrary { for {
charsetRange <- charsetRangesNoQuality
charsetRange <- genCharsetRangeNoQuality
q <- arbitrary[QValue]
} yield charsetRange.withQValue(q) }

Expand All @@ -132,16 +132,20 @@ trait ArbitraryInstances {
implicit lazy val arbitraryCharsetSplatRange: Arbitrary[CharsetRange.`*`] =
Arbitrary { arbitrary[QValue].map(CharsetRange.`*`.withQValue(_)) }

lazy val charsetRangesNoQuality: Gen[CharsetRange] =
def genCharsetRangeNoQuality: Gen[CharsetRange] =
frequency(
3 -> arbitrary[Charset].map(CharsetRange.fromCharset),
1 -> const(CharsetRange.`*`)
)

@deprecated("Use genCharsetRangeNoQuality. This one may cause deadlocks.", "0.15.7")
lazy val charsetRangesNoQuality: Gen[CharsetRange] =
genCharsetRangeNoQuality

implicit lazy val arbitraryAcceptCharset: Arbitrary[`Accept-Charset`] =
Arbitrary { for {
// make a set first so we don't have contradictory q-values
charsetRanges <- nonEmptyContainerOf[Set, CharsetRange](charsetRangesNoQuality).map(_.toVector)
charsetRanges <- nonEmptyContainerOf[Set, CharsetRange](genCharsetRangeNoQuality).map(_.toVector)
qValues <- containerOfN[Vector, QValue](charsetRanges.size, arbitraryQValue.arbitrary)
charsetRangesWithQ = charsetRanges.zip(qValues).map { case (range, q) => range.withQValue(q) }
} yield `Accept-Charset`(charsetRangesWithQ.head, charsetRangesWithQ.tail:_*) }
Expand Down

0 comments on commit 0a60cb2

Please sign in to comment.