/ Check-in [5622a1e2]
Login

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

Overview
Comment:Make sure the queueMutex is held prior to writing the pQueueLast field of the write queue in the async demonstration code. Ticket #3405. (CVS 5744)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5622a1e285fc4d5720f7180a0eb551952f2df331
User & Date: drh 2008-09-26 20:02:50
Context
2008-09-26
21:08
Add the "truncate" journal mode which commits transactions by truncating the rollback journal file to zero length and not calling fsync(). (CVS 5745) check-in: 7c561f2e user: drh tags: trunk
20:02
Make sure the queueMutex is held prior to writing the pQueueLast field of the write queue in the async demonstration code. Ticket #3405. (CVS 5744) check-in: 5622a1e2 user: drh tags: trunk
17:31
Performance enhancement: avoid calling reparentChildPages() from balance_nonroot(). (CVS 5743) check-in: 28fd0a50 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_async.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13         -** $Id: test_async.c,v 1.47 2008/09/15 15:49:34 danielk1977 Exp $
           13  +** $Id: test_async.c,v 1.48 2008/09/26 20:02:50 drh Exp $
    14     14   **
    15     15   ** This file contains an example implementation of an asynchronous IO 
    16     16   ** backend for SQLite.
    17     17   **
    18     18   ** WHAT IS ASYNCHRONOUS I/O?
    19     19   **
    20     20   ** With asynchronous I/O, write requests are handled by a separate thread
................................................................................
   566    566     aHolder[iIdx] = 0;
   567    567     rc = pthread_cond_wait(pCond, pMutex);
   568    568     if( rc==0 ){
   569    569       aHolder[iIdx] = pthread_self();
   570    570     }
   571    571     return rc;
   572    572   }
          573  +
          574  +/*
          575  +** Assert that the mutex is held by the current thread.
          576  +*/
          577  +static void assert_mutex_is_held(pthread_mutex_t *pMutex){
          578  +  int iIdx;
          579  +  pthread_mutex_t *aMutex = (pthread_mutex_t *)(&async);
          580  +  pthread_t *aHolder = (pthread_t *)(&asyncdebug);
          581  +
          582  +  for(iIdx=0; iIdx<3; iIdx++){
          583  +    if( pMutex==&aMutex[iIdx] ) break;
          584  +  }
          585  +  assert(iIdx<3);
          586  +  assert( aHolder[iIdx]==pthread_self() );
          587  +}
   573    588   
   574    589   /* Call our async_XX wrappers instead of selected pthread_XX functions */
   575    590   #define pthread_mutex_lock    async_mutex_lock
   576    591   #define pthread_mutex_unlock  async_mutex_unlock
   577    592   #define pthread_mutex_trylock async_mutex_trylock
   578    593   #define pthread_cond_wait     async_cond_wait
   579    594   
          595  +#else    /* if defined(NDEBUG) */
          596  +
          597  +#define assert_mutex_is_held(X)    /* A no-op when not debugging */
          598  +
   580    599   #endif   /* !defined(NDEBUG) */
   581    600   
   582    601   /*
   583    602   ** Add an entry to the end of the global write-op list. pWrite should point 
   584    603   ** to an AsyncWrite structure allocated using sqlite3_malloc().  The writer
   585    604   ** thread will call sqlite3_free() to free the structure after the specified
   586    605   ** operation has been completed.
................................................................................
  1478   1497           ** structures for this file. Obtain the async.lockMutex mutex 
  1479   1498           ** before doing so.
  1480   1499           */
  1481   1500           pthread_mutex_lock(&async.lockMutex);
  1482   1501           rc = unlinkAsyncFile(pData);
  1483   1502           pthread_mutex_unlock(&async.lockMutex);
  1484   1503   
         1504  +        if( !holdingMutex ){
         1505  +          pthread_mutex_lock(&async.queueMutex);
         1506  +          holdingMutex = 1;
         1507  +        }
         1508  +        assert_mutex_is_held(&async.queueMutex);
  1485   1509           async.pQueueFirst = p->pNext;
  1486   1510           sqlite3_free(pData);
  1487   1511           doNotFree = 1;
  1488   1512           break;
  1489   1513         }
  1490   1514   
  1491   1515         case ASYNC_UNLOCK: {
................................................................................
  1530   1554         holdingMutex = 1;
  1531   1555       }
  1532   1556       /* ASYNC_TRACE(("UNLINK %p\n", p)); */
  1533   1557       if( p==async.pQueueLast ){
  1534   1558         async.pQueueLast = 0;
  1535   1559       }
  1536   1560       if( !doNotFree ){
         1561  +      assert_mutex_is_held(&async.queueMutex);
  1537   1562         async.pQueueFirst = p->pNext;
  1538   1563         sqlite3_free(p);
  1539   1564       }
  1540   1565       assert( holdingMutex );
  1541   1566   
  1542   1567       /* An IO error has occured. We cannot report the error back to the
  1543   1568       ** connection that requested the I/O since the error happened