~drizzle-trunk/drizzle/development

Viewing all changes in revision 1252.1.1.

  • 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().

expand all expand all

Show diffs side-by-side

added added

removed removed

Lines of Context: