sqlite.h


Mutexes

sqlite3_mutex *sqlite3_mutex_alloc(int);
void sqlite3_mutex_free(sqlite3_mutex*);
void sqlite3_mutex_enter(sqlite3_mutex*);
int sqlite3_mutex_try(sqlite3_mutex*);
void sqlite3_mutex_leave(sqlite3_mutex*);

El núclero de SQLite usa estas funciones para la sincronización de hilos. A pesar de que están destinados para uso interno de SQLite, al código que se enlaza con SQLite se le permite utilizar cualquiera de estas funciones.

El código fuente de SQLite contiene múltiples implementaciones de estas funciones mutex.La implementación adecuada se selecciona automáticamente durante la compilación. Están disponibles las siguientes implementaciones en el núcleo de SQLite:

  • SQLITE_MUTEX_OS2
  • SQLITE_MUTEX_PTHREAD
  • SQLITE_MUTEX_W32
  • SQLITE_MUTEX_NOOP

La implementación SQLITE_MUTEX_NOOP es un conjunto de rutinas que no hacen un bloqueo real y es apropiado para usarse con aplicaciones en un único hilo. Las implementaciones SQLITE_MUTEX_OS2, SQLITE_MUTEX_PTHREAD y SQLITE_MUTEX_W32 son apropiadas para usarse con OS/2, Unix y Windows.

Si SQLite es compilado con la macro del preprocesador SQLITE_MUTEX_APPDEF activada (con "-DSQLITE_MUTEX_APPDEF=1"), no se incluye ninguna implementación de mutex con la biblioteca. En ese caso la aplicación debe suministrar una implementación de mutex a medida usando la opción SQLITE_CONFIG_MUTEX de la función sqlite3_config() antes de llamar a sqlite3_initialize() o cualquier otra función pública sqlite3_ que llame a sqlite3_initialize().

La función sqlite3_mutex_alloc() asigna un nuevo mutex y devuelve un puntero a él. Si el valor de retorno es NULL significa que el mutex no pudo ser asignado. SQLite descargará su pila y retornará un error. El argumento para sqlite3_mutex_alloc() es una de estas constantes enteras:

  • SQLITE_MUTEX_FAST
  • SQLITE_MUTEX_RECURSIVE
  • SQLITE_MUTEX_STATIC_MASTER
  • SQLITE_MUTEX_STATIC_MEM
  • SQLITE_MUTEX_STATIC_MEM2
  • SQLITE_MUTEX_STATIC_PRNG
  • SQLITE_MUTEX_STATIC_LRU
  • SQLITE_MUTEX_STATIC_LRU2

Las primeras dos constantes (SQLITE_MUTEX_FAST y SQLITE_MUTEX_RECURSIVE) hacen que sqlite3_mutex_alloc() cree un nuevo mutex. El nuevo mutex es recursivo cuando se usa SQLITE_MUTEX_RECURSIVE pero no necesariamente cuando se usa SQLITE_MUTEX_FAST. La implementación del mutex no necesita hacer distinción entre SQLITE_MUTEX_RECURSIVE y SQLITE_MUTEX_FAST si no quiere. SQLite sólo pide un mutex recursivo en casos donde realmente lo necesita. Si está disponible una implementación de mutex más rápida no recursiva en la plataforma del host, el subsistema de mutex podría retornar un mutex en respuesta a SQLITE_MUTEX_FAST.

Cada uno de los otros parámetros permitidos para sqlite3_mutex_alloc() (cualquiera que no sea SQLITE_MUTEX_FAST o SQLITE_MUTEX_RECURSIVE) devuelve un puntero a un mutex estático preexistente. Para la versión actual de SQLite se usan seis mutexes estáticos. Futuras versiones de SQLite podrán añadir mutexes estáticos adicionales. Los mutexes estáticos son sólo para uso interno de SQLite. Las aplicaciones que usen mutexes SQLite deben usar sñolo mutexes dinámicos devueltos por SQLITE_MUTEX_FAST o SQLITE_MUTEX_RECURSIVE.

Hay que tener en cuenta que si se usa uno de los parámetros de mutex dinámico (SQLITE_MUTEX_FAST o SQLITE_MUTEX_RECURSIVE) entonces sqlite3_mutex_alloc() devuelve un mutex diferente para cada llamada. Pero para los tipos estáticos de mutex, se devuelve el mismo mutex para cada llamada que tenga el mismo número de tipo.

La función sqlite3_mutex_free() libera un mutex dinámico previamente asignado. SQLite está pendiente de liberar cada mutex dinámico que haya asignado. Los mutexes dinámicos no deben estar en uso cuando son liberados. Los intentos de liberar un mutex estático producen un comportamiento indefinido. SQLite nunca libera un mutex estático.

Las funciones sqlite3_mutex_enter() y sqlite3_mutex_try() intentan ingresar en un mutex. Si otro hilo ya está dentro del mutex, sqlite3_mutex_enter() se bloqueará y sqlite3_mutex_try() retornará SQLITE_BUSY. La función sqlite3_mutex_try() devolverá SQLITE_OK si la entrada tiene éxito. Los mutexes creados usando SQLITE_MUTEX_RECURSIVE se pueden introducir varias veces por el mismo hilo. En esos casos, el mutex debe ser abandonado un número de veces igual antes de que otro hilo pueda entrar. Si el mismo hilo intenta entrar en cualquier otro tipo de mutex más de una vez, el comportamiento es indefinido. SQLite nunca mostraré ese comportamiento en el uso de sus propios mutexes.

Algunos sistemas (por ejemplo, Windows 95) no soportan la operación implementada por sqlite3_mutex_try(). En esos sistemas, sqlite3_mutex_try() siempre retornará SQLITE_BUSY. El núcleo de SQLite sólo utiliza sqlite3_mutex_try() como una optimización, por lo que este comportamiento es aceptable.

La función sqlite3_mutex_leave() sale de un mutex en el que se entró previamente desde el mismo hilo. El comportamiento es indefinido si el mutex no ha sido introducido por el hilo que la invoca o no está actualmente asignado. SQLite nunca hace eso.

Si el argumento para sqlite3_mutex_enter(), sqlite3_mutex_try() o sqlite3_mutex_leave es un puntero NULL, ninguna de las tres funciones hace nada.

Ver también: sqlite3_mutex_held() y sqlite3_mutex_notheld().