dbsql/src/safety.c
2007-03-10 20:04:07 +01:00

104 lines
3 KiB
C

/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* $Id: safety.c 7 2007-02-03 13:34:17Z gburd $
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __safety_on --
* Change the sqlite.magic from DBSQL_STATUS_OPEN to DBSQL_STATUS_BUSY.
* Return an error (non-zero) if the magic was not DBSQL_STATUS_OPEN
* when this routine is called.
*
* !!! TODO race condition
* This routine is a attempt to detect if two threads use the
* same DBSQL* pointer at the same time. There is a race
* condition so it is possible that the error is not detected.
* But usually the problem will be seen. The result will be an
* error which can be used to debug the application that is
* using the library incorrectly.
*
* [#202sl]: If db->magic is not a valid open value, take care not
* to modify the db structure at all. It could be that db is a stale
* pointer. In other words, it could be that there has been a prior
* call to DBSQL->close(db) and db has been deallocated. And we do
* not want to write into deallocated memory.
*
* PUBLIC: int __safety_on __P((DBSQL *));
*/
int
__safety_on(dbp)
DBSQL *dbp;
{
if (dbp->magic == DBSQL_STATUS_OPEN) {
dbp->magic = DBSQL_STATUS_BUSY;
return 0;
} else if (dbp->magic == DBSQL_STATUS_BUSY ||
dbp->magic == DBSQL_STATUS_ERROR ||
dbp->want_to_close) {
dbp->magic = DBSQL_STATUS_ERROR;
dbp->flags |= DBSQL_Interrupt;
}
return 1;
}
/*
* __safety_off --
* Change the magic from DBSQL_STATUS_BUSY to DBSQL_STATUS_OPEN.
* Return an error (non-zero) if the magic was not DBSQL_STATUS_BUSY
* when this routine is called.
*
* PUBLIC: int __safety_off __P((DBSQL *));
*/
int
__safety_off(dbp)
DBSQL *dbp;
{
if (dbp->magic == DBSQL_STATUS_BUSY) {
dbp->magic = DBSQL_STATUS_OPEN;
return 0;
} else if (dbp->magic == DBSQL_STATUS_OPEN ||
dbp->magic == DBSQL_STATUS_ERROR ||
dbp->want_to_close) {
dbp->magic = DBSQL_STATUS_ERROR;
dbp->flags |= DBSQL_Interrupt;
}
return 1;
}
/*
* __safety_check --
* Check to make sure we are not currently executing an DBSQL->exec().
* If we are currently in an DBSQL->exec(), return true and set
* dbsql_t.magic to DBSQL_STATUS_ERROR. This will cause a complete
* shutdown of the database. This routine is used to try to detect
* when API routines are called at the wrong time or in the wrong
* sequence.
*
* PUBLIC: int __safety_check __P((DBSQL *));
*/
int
__safety_check(dbp)
DBSQL *dbp;
{
if (dbp->pVdbe != 0) {
dbp->magic = DBSQL_STATUS_ERROR;
return 1;
}
return 0;
}