Code review comment for lp:~jaypipes/drizzle/bugs

Revision history for this message
Jay Pipes (jaypipes) wrote :

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

« Back to merge proposal