SQLite

Check-in [5622a1e285]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5622a1e285fc4d5720f7180a0eb551952f2df331
User & Date: drh 2008-09-26 20:02:50.000
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: 7c561f2e92 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: 5622a1e285 user: drh tags: trunk)
17:31
Performance enhancement: avoid calling reparentChildPages() from balance_nonroot(). (CVS 5743) (check-in: 28fd0a50ca user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_async.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
** 2005 December 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: test_async.c,v 1.47 2008/09/15 15:49:34 danielk1977 Exp $
**
** This file contains an example implementation of an asynchronous IO 
** backend for SQLite.
**
** WHAT IS ASYNCHRONOUS I/O?
**
** With asynchronous I/O, write requests are handled by a separate thread












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
** 2005 December 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: test_async.c,v 1.48 2008/09/26 20:02:50 drh Exp $
**
** This file contains an example implementation of an asynchronous IO 
** backend for SQLite.
**
** WHAT IS ASYNCHRONOUS I/O?
**
** With asynchronous I/O, write requests are handled by a separate thread
566
567
568
569
570
571
572















573
574
575
576
577
578
579




580
581
582
583
584
585
586
  aHolder[iIdx] = 0;
  rc = pthread_cond_wait(pCond, pMutex);
  if( rc==0 ){
    aHolder[iIdx] = pthread_self();
  }
  return rc;
}
















/* Call our async_XX wrappers instead of selected pthread_XX functions */
#define pthread_mutex_lock    async_mutex_lock
#define pthread_mutex_unlock  async_mutex_unlock
#define pthread_mutex_trylock async_mutex_trylock
#define pthread_cond_wait     async_cond_wait





#endif   /* !defined(NDEBUG) */

/*
** Add an entry to the end of the global write-op list. pWrite should point 
** to an AsyncWrite structure allocated using sqlite3_malloc().  The writer
** thread will call sqlite3_free() to free the structure after the specified
** operation has been completed.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
  aHolder[iIdx] = 0;
  rc = pthread_cond_wait(pCond, pMutex);
  if( rc==0 ){
    aHolder[iIdx] = pthread_self();
  }
  return rc;
}

/*
** Assert that the mutex is held by the current thread.
*/
static void assert_mutex_is_held(pthread_mutex_t *pMutex){
  int iIdx;
  pthread_mutex_t *aMutex = (pthread_mutex_t *)(&async);
  pthread_t *aHolder = (pthread_t *)(&asyncdebug);

  for(iIdx=0; iIdx<3; iIdx++){
    if( pMutex==&aMutex[iIdx] ) break;
  }
  assert(iIdx<3);
  assert( aHolder[iIdx]==pthread_self() );
}

/* Call our async_XX wrappers instead of selected pthread_XX functions */
#define pthread_mutex_lock    async_mutex_lock
#define pthread_mutex_unlock  async_mutex_unlock
#define pthread_mutex_trylock async_mutex_trylock
#define pthread_cond_wait     async_cond_wait

#else    /* if defined(NDEBUG) */

#define assert_mutex_is_held(X)    /* A no-op when not debugging */

#endif   /* !defined(NDEBUG) */

/*
** Add an entry to the end of the global write-op list. pWrite should point 
** to an AsyncWrite structure allocated using sqlite3_malloc().  The writer
** thread will call sqlite3_free() to free the structure after the specified
** operation has been completed.
1478
1479
1480
1481
1482
1483
1484





1485
1486
1487
1488
1489
1490
1491
        ** structures for this file. Obtain the async.lockMutex mutex 
        ** before doing so.
        */
        pthread_mutex_lock(&async.lockMutex);
        rc = unlinkAsyncFile(pData);
        pthread_mutex_unlock(&async.lockMutex);






        async.pQueueFirst = p->pNext;
        sqlite3_free(pData);
        doNotFree = 1;
        break;
      }

      case ASYNC_UNLOCK: {







>
>
>
>
>







1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
        ** structures for this file. Obtain the async.lockMutex mutex 
        ** before doing so.
        */
        pthread_mutex_lock(&async.lockMutex);
        rc = unlinkAsyncFile(pData);
        pthread_mutex_unlock(&async.lockMutex);

        if( !holdingMutex ){
          pthread_mutex_lock(&async.queueMutex);
          holdingMutex = 1;
        }
        assert_mutex_is_held(&async.queueMutex);
        async.pQueueFirst = p->pNext;
        sqlite3_free(pData);
        doNotFree = 1;
        break;
      }

      case ASYNC_UNLOCK: {
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
      holdingMutex = 1;
    }
    /* ASYNC_TRACE(("UNLINK %p\n", p)); */
    if( p==async.pQueueLast ){
      async.pQueueLast = 0;
    }
    if( !doNotFree ){

      async.pQueueFirst = p->pNext;
      sqlite3_free(p);
    }
    assert( holdingMutex );

    /* An IO error has occured. We cannot report the error back to the
    ** connection that requested the I/O since the error happened 







>







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
      holdingMutex = 1;
    }
    /* ASYNC_TRACE(("UNLINK %p\n", p)); */
    if( p==async.pQueueLast ){
      async.pQueueLast = 0;
    }
    if( !doNotFree ){
      assert_mutex_is_held(&async.queueMutex);
      async.pQueueFirst = p->pNext;
      sqlite3_free(p);
    }
    assert( holdingMutex );

    /* An IO error has occured. We cannot report the error back to the
    ** connection that requested the I/O since the error happened