/ Check-in [d7bb7ea4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add extra tests to threadtest4.c. Fix a benign data race accessing the text encoding using ENC(db).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d7bb7ea4ab97ad26f4c84c9b8dc2827010093803
User & Date: drh 2014-12-12 23:17:54
Context
2014-12-13
17:41
Further enhancements to threadtest3 stress tests. check-in: ba772cff user: dan tags: trunk
2014-12-12
23:17
Add extra tests to threadtest4.c. Fix a benign data race accessing the text encoding using ENC(db). check-in: d7bb7ea4 user: drh tags: trunk
16:39
Add extra tests to threadtest3. check-in: f6bf86f9 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

  2754   2754         rc = SQLITE_NOMEM;
  2755   2755       }
  2756   2756       sqlite3Error(db, rc);
  2757   2757       goto opendb_out;
  2758   2758     }
  2759   2759     sqlite3BtreeEnter(db->aDb[0].pBt);
  2760   2760     db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
         2761  +  if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
  2761   2762     sqlite3BtreeLeave(db->aDb[0].pBt);
  2762   2763     db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
  2763   2764   
  2764   2765     /* The default safety_level for the main database is 'full'; for the temp
  2765   2766     ** database it is 'NONE'. This matches the pager layer defaults.  
  2766   2767     */
  2767   2768     db->aDb[0].zName = "main";
................................................................................
  2912   2913     sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  2913   2914     zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  2914   2915     if( zFilename8 ){
  2915   2916       rc = openDatabase(zFilename8, ppDb,
  2916   2917                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
  2917   2918       assert( *ppDb || rc==SQLITE_NOMEM );
  2918   2919       if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
  2919         -      ENC(*ppDb) = SQLITE_UTF16NATIVE;
         2920  +      SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
  2920   2921       }
  2921   2922     }else{
  2922   2923       rc = SQLITE_NOMEM;
  2923   2924     }
  2924   2925     sqlite3ValueFree(pVal);
  2925   2926   
  2926   2927     return sqlite3ApiExit(0, rc);

Changes to src/pragma.c.

  2076   2076         */
  2077   2077         if( 
  2078   2078           !(DbHasProperty(db, 0, DB_SchemaLoaded)) || 
  2079   2079           DbHasProperty(db, 0, DB_Empty) 
  2080   2080         ){
  2081   2081           for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
  2082   2082             if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
  2083         -            ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
         2083  +            SCHEMA_ENC(db) = ENC(db) =
         2084  +                pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
  2084   2085               break;
  2085   2086             }
  2086   2087           }
  2087   2088           if( !pEnc->zName ){
  2088   2089             sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
  2089   2090           }
  2090   2091         }

Changes to src/prepare.c.

   390    390   ** file was of zero-length, then the DB_Empty flag is also set.
   391    391   */
   392    392   int sqlite3Init(sqlite3 *db, char **pzErrMsg){
   393    393     int i, rc;
   394    394     int commit_internal = !(db->flags&SQLITE_InternChanges);
   395    395     
   396    396     assert( sqlite3_mutex_held(db->mutex) );
          397  +  assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
   397    398     assert( db->init.busy==0 );
   398    399     rc = SQLITE_OK;
   399    400     db->init.busy = 1;
          401  +  ENC(db) = SCHEMA_ENC(db);
   400    402     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
   401    403       if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
   402    404       rc = sqlite3InitOne(db, i, pzErrMsg);
   403    405       if( rc ){
   404    406         sqlite3ResetOneSchema(db, i);
   405    407       }
   406    408     }

Changes to src/sqliteInt.h.

  1055   1055     int flags;                    /* Miscellaneous flags. See below */
  1056   1056     i64 lastRowid;                /* ROWID of most recent insert (see above) */
  1057   1057     i64 szMmap;                   /* Default mmap_size setting */
  1058   1058     unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  1059   1059     int errCode;                  /* Most recent error code (SQLITE_*) */
  1060   1060     int errMask;                  /* & result codes with this before returning */
  1061   1061     u16 dbOptFlags;               /* Flags to enable/disable optimizations */
         1062  +  u8 enc;                       /* Text encoding */
  1062   1063     u8 autoCommit;                /* The auto-commit flag. */
  1063   1064     u8 temp_store;                /* 1: file 2: memory 0: default */
  1064   1065     u8 mallocFailed;              /* True if we have seen a malloc failure */
  1065   1066     u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  1066   1067     signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  1067   1068     u8 suppressErr;               /* Do not issue error messages if true */
  1068   1069     u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
................................................................................
  1156   1157     sqlite3_userauth auth;        /* User authentication information */
  1157   1158   #endif
  1158   1159   };
  1159   1160   
  1160   1161   /*
  1161   1162   ** A macro to discover the encoding of a database.
  1162   1163   */
  1163         -#define ENC(db) ((db)->aDb[0].pSchema->enc)
         1164  +#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
         1165  +#define ENC(db)        ((db)->enc)
  1164   1166   
  1165   1167   /*
  1166   1168   ** Possible values for the sqlite3.flags.
  1167   1169   */
  1168   1170   #define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
  1169   1171   #define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
  1170   1172   #define SQLITE_FullFSync      0x00000004  /* Use full fsync on the backend */

Changes to test/threadtest4.c.

   301    301       worker_trace(p, "query [%s]", sqlite3_sql(pStmt));
   302    302       rc = sqlite3_step(pStmt);
   303    303       if( rc!=SQLITE_ROW ){
   304    304         worker_error(p, "Failed to step: %s", sqlite3_sql(pStmt));
   305    305       }else if( sqlite3_column_int(pStmt, 0)!=400 ){
   306    306         worker_error(p, "Wrong result: %d", sqlite3_column_int(pStmt,0));
   307    307       }
   308         -    if( p->nErr ) break;
   309    308       sqlite3_finalize(pStmt);
          309  +    if( p->nErr ) break;
   310    310   
   311    311       if( ((iOuter+p->tid)%3)==0 ){
   312    312         sqlite3_db_release_memory(p->db);
   313    313         p->nTest++;
   314    314       }
          315  +
          316  +    pthread_mutex_lock(p->pWrMutex);
          317  +    run_sql(p, "BEGIN;");
          318  +    run_sql(p, "UPDATE t1 SET c=NULL WHERE a=55");
          319  +    run_sql(p, "UPDATE t2 SET f=NULL WHERE d=42");
          320  +    run_sql(p, "UPDATE t3 SET z=NULL WHERE x=31");
          321  +    run_sql(p, "ROLLBACK;");
          322  +    p->nTest++;
          323  +    pthread_mutex_unlock(p->pWrMutex);
          324  +
   315    325   
   316    326       if( iOuter==p->tid ){
   317    327         pthread_mutex_lock(p->pWrMutex);
   318    328         run_sql(p, "VACUUM");
   319    329         pthread_mutex_unlock(p->pWrMutex);
   320    330       }
          331  +
          332  +    pStmt = prep_sql(p->db,
          333  +       "SELECT t1.rowid, t2.rowid, t3.rowid"
          334  +       "  FROM t1, t2, t3"
          335  +       " WHERE t1.tid=%d AND t2.tid=%d AND t3.tid=%d"
          336  +       "   AND t1.a<>t2.d AND t2.d<>t3.x"
          337  +       " ORDER BY 1, 2, 3"
          338  +       ,p->tid, p->tid, p->tid);
          339  +    worker_trace(p, "query [%s]", sqlite3_sql(pStmt));
          340  +    for(i=0; i<p->nWorker; i++){
          341  +      rc = sqlite3_step(pStmt);
          342  +      if( rc!=SQLITE_ROW ){
          343  +        worker_error(p, "Failed to step: %s", sqlite3_sql(pStmt));
          344  +        break;
          345  +      }
          346  +      sched_yield();
          347  +    }
          348  +    sqlite3_finalize(pStmt);
          349  +    if( p->nErr ) break;
   321    350   
   322    351       worker_delete_all_content(p, (p->tid+iOuter)%2);
   323    352       worker_close_connection(p);
   324    353       p->db = 0;
   325    354     }
   326    355     worker_close_connection(p);
   327    356     printf("worker %d finished\n", p->tid); fflush(stdout);