-
Committer:
Jay Pipes
-
Date:
2009-12-24 22:16:14 UTC
-
mto:
This revision was merged to the branch mainline in
revision
1254.
-
Revision ID:
jpipes@serialcoder-20091224221614-230j8vbqtfgqnt0c
Fixes LP Bug #500031:
"dbt2 fails with 1024 connections"
After investigation into this, I discovered that there was a
race condition in TemporalFormat::match():
TemporalFormat::_re is the compiled PCRE regular expression object
inside each of the TemporalFormat objects, which are shared
among all threads and live in global scope.
Unfortunately, TemporalFormat::match() was using the member
variable TemporalFormat::_match_vector as its match state.
At high concurrency, this means that the following race
condition could happen:
Thread 1 executes pcre_exec() and finds a match, therefore
populating TemporalFormat::_match_vector of integers
with the position offsets of the matched pieces of the temporal object.
Thread 1, during construction of the Temporal output of
TemporalFormat::match(), uses these _match_vector position
offsets in calling std::string::substr on a copy of the
matched string, essentially "cutting up" the string
into year, month, day, etc.
Thread 2 executes pcre_exec() and also finds a match,
thereby changing TemporalFormat::_match_vector to something
different
Thread 1 continues trying to use std::string::substr(),
but now uses offsets that are invalid for its string,
thereby producing an out_of_range exception.
The solution is to pull the TemporalFormat::_match_vector
member variable and instead put a function-scope-level
match_vector variable on the stack inside TemporalFormat::match().