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: |
5622a1e285fc4d5720f7180a0eb55195 |
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
Changes to src/test_async.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 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. ** ************************************************************************* ** | | | 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 |
︙ | ︙ |