extensions/sqlite/sqlite-source/mutex.c
author Asher Baker <asherkin@gmail.com>
Thu Apr 26 16:58:18 2012 +0100 (2012-04-26)
changeset 3488 bee90c8ef6c3
parent 1645 27307df4d711
permissions -rw-r--r--
Fixed client serials not being unique on Windows (bug 5285, r=psychonic).
dvander@1645
     1
/*
dvander@1645
     2
** 2007 August 14
dvander@1645
     3
**
dvander@1645
     4
** The author disclaims copyright to this source code.  In place of
dvander@1645
     5
** a legal notice, here is a blessing:
dvander@1645
     6
**
dvander@1645
     7
**    May you do good and not evil.
dvander@1645
     8
**    May you find forgiveness for yourself and forgive others.
dvander@1645
     9
**    May you share freely, never taking more than you give.
dvander@1645
    10
**
dvander@1645
    11
*************************************************************************
dvander@1645
    12
** This file contains the C functions that implement mutexes.
dvander@1645
    13
**
dvander@1645
    14
** The implementation in this file does not provide any mutual
dvander@1645
    15
** exclusion and is thus suitable for use only in applications
dvander@1645
    16
** that use SQLite in a single thread.  But this implementation
dvander@1645
    17
** does do a lot of error checking on mutexes to make sure they
dvander@1645
    18
** are called correctly and at appropriate times.  Hence, this
dvander@1645
    19
** implementation is suitable for testing.
dvander@1645
    20
** debugging purposes
dvander@1645
    21
**
dvander@1645
    22
** $Id$
dvander@1645
    23
*/
dvander@1645
    24
#include "sqliteInt.h"
dvander@1645
    25
dvander@1645
    26
#ifdef SQLITE_MUTEX_NOOP_DEBUG
dvander@1645
    27
/*
dvander@1645
    28
** In this implementation, mutexes do not provide any mutual exclusion.
dvander@1645
    29
** But the error checking is provided.  This implementation is useful
dvander@1645
    30
** for test purposes.
dvander@1645
    31
*/
dvander@1645
    32
dvander@1645
    33
/*
dvander@1645
    34
** The mutex object
dvander@1645
    35
*/
dvander@1645
    36
struct sqlite3_mutex {
dvander@1645
    37
  int id;     /* The mutex type */
dvander@1645
    38
  int cnt;    /* Number of entries without a matching leave */
dvander@1645
    39
};
dvander@1645
    40
dvander@1645
    41
/*
dvander@1645
    42
** The sqlite3_mutex_alloc() routine allocates a new
dvander@1645
    43
** mutex and returns a pointer to it.  If it returns NULL
dvander@1645
    44
** that means that a mutex could not be allocated. 
dvander@1645
    45
*/
dvander@1645
    46
sqlite3_mutex *sqlite3_mutex_alloc(int id){
dvander@1645
    47
  static sqlite3_mutex aStatic[5];
dvander@1645
    48
  sqlite3_mutex *pNew = 0;
dvander@1645
    49
  switch( id ){
dvander@1645
    50
    case SQLITE_MUTEX_FAST:
dvander@1645
    51
    case SQLITE_MUTEX_RECURSIVE: {
dvander@1645
    52
      pNew = sqlite3_malloc(sizeof(*pNew));
dvander@1645
    53
      if( pNew ){
dvander@1645
    54
        pNew->id = id;
dvander@1645
    55
        pNew->cnt = 0;
dvander@1645
    56
      }
dvander@1645
    57
      break;
dvander@1645
    58
    }
dvander@1645
    59
    default: {
dvander@1645
    60
      assert( id-2 >= 0 );
dvander@1645
    61
      assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
dvander@1645
    62
      pNew = &aStatic[id-2];
dvander@1645
    63
      pNew->id = id;
dvander@1645
    64
      break;
dvander@1645
    65
    }
dvander@1645
    66
  }
dvander@1645
    67
  return pNew;
dvander@1645
    68
}
dvander@1645
    69
dvander@1645
    70
/*
dvander@1645
    71
** This routine deallocates a previously allocated mutex.
dvander@1645
    72
*/
dvander@1645
    73
void sqlite3_mutex_free(sqlite3_mutex *p){
dvander@1645
    74
  assert( p );
dvander@1645
    75
  assert( p->cnt==0 );
dvander@1645
    76
  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
dvander@1645
    77
  sqlite3_free(p);
dvander@1645
    78
}
dvander@1645
    79
dvander@1645
    80
/*
dvander@1645
    81
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
dvander@1645
    82
** to enter a mutex.  If another thread is already within the mutex,
dvander@1645
    83
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
dvander@1645
    84
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
dvander@1645
    85
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
dvander@1645
    86
** be entered multiple times by the same thread.  In such cases the,
dvander@1645
    87
** mutex must be exited an equal number of times before another thread
dvander@1645
    88
** can enter.  If the same thread tries to enter any other kind of mutex
dvander@1645
    89
** more than once, the behavior is undefined.
dvander@1645
    90
*/
dvander@1645
    91
void sqlite3_mutex_enter(sqlite3_mutex *p){
dvander@1645
    92
  assert( p );
dvander@1645
    93
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
dvander@1645
    94
  p->cnt++;
dvander@1645
    95
}
dvander@1645
    96
int sqlite3_mutex_try(sqlite3_mutex *p){
dvander@1645
    97
  assert( p );
dvander@1645
    98
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
dvander@1645
    99
  p->cnt++;
dvander@1645
   100
  return SQLITE_OK;
dvander@1645
   101
}
dvander@1645
   102
dvander@1645
   103
/*
dvander@1645
   104
** The sqlite3_mutex_leave() routine exits a mutex that was
dvander@1645
   105
** previously entered by the same thread.  The behavior
dvander@1645
   106
** is undefined if the mutex is not currently entered or
dvander@1645
   107
** is not currently allocated.  SQLite will never do either.
dvander@1645
   108
*/
dvander@1645
   109
void sqlite3_mutex_leave(sqlite3_mutex *p){
dvander@1645
   110
  assert( p );
dvander@1645
   111
  assert( sqlite3_mutex_held(p) );
dvander@1645
   112
  p->cnt--;
dvander@1645
   113
  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
dvander@1645
   114
}
dvander@1645
   115
dvander@1645
   116
/*
dvander@1645
   117
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
dvander@1645
   118
** intended for use inside assert() statements.
dvander@1645
   119
*/
dvander@1645
   120
int sqlite3_mutex_held(sqlite3_mutex *p){
dvander@1645
   121
  return p==0 || p->cnt>0;
dvander@1645
   122
}
dvander@1645
   123
int sqlite3_mutex_notheld(sqlite3_mutex *p){
dvander@1645
   124
  return p==0 || p->cnt==0;
dvander@1645
   125
}
dvander@1645
   126
#endif /* SQLITE_MUTEX_NOOP_DEBUG */