engine/sqlite/src/btmutex.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2007 August 27
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** $Id: btmutex.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** This file contains code used to implement mutexes on Btree objects.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
** This code really belongs in btree.c.  But btree.c is getting too
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
** big and we want to break it down some.  This packaged seemed like
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
** a good breakout.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
#include "btreeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
** Enter a mutex on the given BTree object.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
** If the object is not sharable, then no mutex is ever required
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** and this routine is a no-op.  The underlying mutex is non-recursive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** But we keep a reference count in Btree.wantToLock so the behavior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
** of this interface is recursive.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
** To avoid deadlocks, multiple Btrees are locked in the same order
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
** by all database connections.  The p->pNext is a list of other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
** Btrees belonging to the same database connection as the p Btree
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
** which need to be locked after p.  If we cannot get a lock on
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
** p, then first unlock all of the others on p->pNext, then wait
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
** for the lock to become available on p, then relock all of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
** subsequent Btrees that desire a lock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
void sqlite3BtreeEnter(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  Btree *pLater;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  /* Some basic sanity checking on the Btree.  The list of Btrees
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  ** connected by pNext and pPrev should be in sorted order by
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  ** Btree.pBt value. All elements of the list should belong to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  ** the same connection. Only shared Btrees are on the list. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
  assert( p->pNext==0 || p->pNext->pBt>p->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  assert( p->pNext==0 || p->pNext->db==p->db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  assert( p->pPrev==0 || p->pPrev->db==p->db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
  /* Check for locking consistency */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  assert( !p->locked || p->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  assert( p->sharable || p->wantToLock==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  /* We should already hold a lock on the database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  if( !p->sharable ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
  p->wantToLock++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
  if( p->locked ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
  /* In most cases, we should be able to acquire the lock we
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
  ** want without having to go throught the ascending lock
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
  ** procedure that follows.  Just be sure not to block.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
    p->locked = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  /* To avoid deadlock, first release all locks with a larger
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
  ** BtShared address.  Then acquire our lock.  Then reacquire
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  ** the other BtShared locks that we used to hold in ascending
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  ** order.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
  for(pLater=p->pNext; pLater; pLater=pLater->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
    assert( pLater->sharable );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
    assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
    assert( !pLater->locked || pLater->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
    if( pLater->locked ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
      sqlite3_mutex_leave(pLater->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
      pLater->locked = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
  sqlite3_mutex_enter(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  p->locked = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
  for(pLater=p->pNext; pLater; pLater=pLater->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
    if( pLater->wantToLock ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
      sqlite3_mutex_enter(pLater->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
      pLater->locked = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
** Exit the recursive mutex on a Btree.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
void sqlite3BtreeLeave(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  if( p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
    assert( p->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
    p->wantToLock--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
    if( p->wantToLock==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
      assert( p->locked );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
      sqlite3_mutex_leave(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
      p->locked = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
** Return true if the BtShared mutex is held on the btree.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
** This routine makes no determination one why or another if the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
** database connection mutex is held.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
** This routine is used only from within assert() statements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
int sqlite3BtreeHoldsMutex(Btree *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
  return (p->sharable==0 ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
             (p->locked && p->wantToLock && sqlite3_mutex_held(p->pBt->mutex)));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
#ifndef SQLITE_OMIT_INCRBLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
** Enter and leave a mutex on a Btree given a cursor owned by that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
** Btree.  These entry points are used by incremental I/O and can be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
** omitted if that module is not used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
void sqlite3BtreeEnterCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
  sqlite3BtreeEnter(pCur->pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
void sqlite3BtreeLeaveCursor(BtCursor *pCur){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
  sqlite3BtreeLeave(pCur->pBtree);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
#endif /* SQLITE_OMIT_INCRBLOB */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
** Enter the mutex on every Btree associated with a database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
** connection.  This is needed (for example) prior to parsing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
** a statement since we will be comparing table and column names
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
** against all schemas and we do not want those schemas being
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
** reset out from under us.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
** There is a corresponding leave-all procedures.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
** Enter the mutexes in accending order by BtShared pointer address
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
** to avoid the possibility of deadlock when two threads with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
** two or more btrees in common both try to lock all their btrees
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
** at the same instant.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
void sqlite3BtreeEnterAll(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
  Btree *p, *pLater;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
  assert( sqlite3_mutex_held(db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
    p = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
    if( p && p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
      p->wantToLock++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
      if( !p->locked ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
        assert( p->wantToLock==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
        while( p->pPrev ) p = p->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
        while( p->locked && p->pNext ) p = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
        for(pLater = p->pNext; pLater; pLater=pLater->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
          if( pLater->locked ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
            sqlite3_mutex_leave(pLater->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
            pLater->locked = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
        while( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
          sqlite3_mutex_enter(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
          p->locked++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
          p = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
void sqlite3BtreeLeaveAll(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  Btree *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  assert( sqlite3_mutex_held(db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    p = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
    if( p && p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
      assert( p->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
      p->wantToLock--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
      if( p->wantToLock==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
        assert( p->locked );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
        sqlite3_mutex_leave(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
        p->locked = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
** Return true if the current thread holds the database connection
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
** mutex and all required BtShared mutexes.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
** This routine is used inside assert() statements only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
  if( !sqlite3_mutex_held(db->mutex) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
    Btree *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
    p = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
    if( p && p->sharable &&
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
         (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
#endif /* NDEBUG */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
** Potentially dd a new Btree pointer to a BtreeMutexArray.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
** Really only add the Btree if it can possibly be shared with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
** another database connection.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
** The Btrees are kept in sorted order by pBtree->pBt.  That
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
** way when we go to enter all the mutexes, we can enter them
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
** in order without every having to backup and retry and without
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
** worrying about deadlock.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
** The number of shared btrees will always be small (usually 0 or 1)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
** so an insertion sort is an adequate algorithm here.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
  int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
  BtShared *pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
  if( pBtree==0 || pBtree->sharable==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
    for(i=0; i<pArray->nMutex; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
      assert( pArray->aBtree[i]!=pBtree );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  assert( pArray->nMutex>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  assert( pArray->nMutex<sizeof(pArray->aBtree)/sizeof(pArray->aBtree[0])-1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
  pBt = pBtree->pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
  for(i=0; i<pArray->nMutex; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
    assert( pArray->aBtree[i]!=pBtree );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
    if( pArray->aBtree[i]->pBt>pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
      for(j=pArray->nMutex; j>i; j--){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
        pArray->aBtree[j] = pArray->aBtree[j-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
      pArray->aBtree[i] = pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
      pArray->nMutex++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  pArray->aBtree[pArray->nMutex++] = pBtree;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
** Enter the mutex of every btree in the array.  This routine is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
** called at the beginning of sqlite3VdbeExec().  The mutexes are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
** exited at the end of the same function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
  for(i=0; i<pArray->nMutex; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
    Btree *p = pArray->aBtree[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
    /* Some basic sanity checking */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
    assert( !p->locked || p->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
    /* We should already hold a lock on the database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
    assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
    p->wantToLock++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
    if( !p->locked && p->sharable ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
      sqlite3_mutex_enter(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
      p->locked = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
** Leave the mutex of every btree in the group.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  for(i=0; i<pArray->nMutex; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
    Btree *p = pArray->aBtree[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
    /* Some basic sanity checking */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
    assert( p->locked || !p->sharable );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
    assert( p->wantToLock>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
    /* We should already hold a lock on the database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
    assert( sqlite3_mutex_held(p->db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
    p->wantToLock--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    if( p->wantToLock==0 && p->locked ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
      sqlite3_mutex_leave(p->pBt->mutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
      p->locked = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
#endif  /* SQLITE_THREADSAFE && !SQLITE_OMIT_SHARED_CACHE */