From 2f8d7092bc2c9609fa98d6888106b96f38b22828 Mon Sep 17 00:00:00 2001 From: dan miller Date: Sun, 21 Oct 2007 08:36:32 +0000 Subject: libraries moved to opensim-libs, a new repository --- .../sqlite/unix/sqlite-3.5.1/src/test_server.c | 491 --------------------- 1 file changed, 491 deletions(-) delete mode 100644 libraries/sqlite/unix/sqlite-3.5.1/src/test_server.c (limited to 'libraries/sqlite/unix/sqlite-3.5.1/src/test_server.c') diff --git a/libraries/sqlite/unix/sqlite-3.5.1/src/test_server.c b/libraries/sqlite/unix/sqlite-3.5.1/src/test_server.c deleted file mode 100644 index 624249f..0000000 --- a/libraries/sqlite/unix/sqlite-3.5.1/src/test_server.c +++ /dev/null @@ -1,491 +0,0 @@ -/* -** 2006 January 07 -** -** 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. -** -****************************************************************************** -** -** This file contains demonstration code. Nothing in this file gets compiled -** or linked into the SQLite library unless you use a non-standard option: -** -** -DSQLITE_SERVER=1 -** -** The configure script will never generate a Makefile with the option -** above. You will need to manually modify the Makefile if you want to -** include any of the code from this file in your project. Or, at your -** option, you may copy and paste the code from this file and -** thereby avoiding a recompile of SQLite. -** -** -** This source file demonstrates how to use SQLite to create an SQL database -** server thread in a multiple-threaded program. One or more client threads -** send messages to the server thread and the server thread processes those -** messages in the order received and returns the results to the client. -** -** One might ask: "Why bother? Why not just let each thread connect -** to the database directly?" There are a several of reasons to -** prefer the client/server approach. -** -** (1) Some systems (ex: Redhat9) have broken threading implementations -** that prevent SQLite database connections from being used in -** a thread different from the one where they were created. With -** the client/server approach, all database connections are created -** and used within the server thread. Client calls to the database -** can be made from multiple threads (though not at the same time!) -** -** (2) Beginning with SQLite version 3.3.0, when two or more -** connections to the same database occur within the same thread, -** they can optionally share their database cache. This reduces -** I/O and memory requirements. Cache shared is controlled using -** the sqlite3_enable_shared_cache() API. -** -** (3) Database connections on a shared cache use table-level locking -** instead of file-level locking for improved concurrency. -** -** (4) Database connections on a shared cache can by optionally -** set to READ UNCOMMITTED isolation. (The default isolation for -** SQLite is SERIALIZABLE.) When this occurs, readers will -** never be blocked by a writer and writers will not be -** blocked by readers. There can still only be a single writer -** at a time, but multiple readers can simultaneously exist with -** that writer. This is a huge increase in concurrency. -** -** To summarize the rational for using a client/server approach: prior -** to SQLite version 3.3.0 it probably was not worth the trouble. But -** with SQLite version 3.3.0 and beyond you can get significant performance -** and concurrency improvements and memory usage reductions by going -** client/server. -** -** Note: The extra features of version 3.3.0 described by points (2) -** through (4) above are only available if you compile without the -** option -DSQLITE_OMIT_SHARED_CACHE. -** -** Here is how the client/server approach works: The database server -** thread is started on this procedure: -** -** void *sqlite3_server(void *NotUsed); -** -** The sqlite_server procedure runs as long as the g.serverHalt variable -** is false. A mutex is used to make sure no more than one server runs -** at a time. The server waits for messages to arrive on a message -** queue and processes the messages in order. -** -** Two convenience routines are provided for starting and stopping the -** server thread: -** -** void sqlite3_server_start(void); -** void sqlite3_server_stop(void); -** -** Both of the convenience routines return immediately. Neither will -** ever give an error. If a server is already started or already halted, -** then the routines are effectively no-ops. -** -** Clients use the following interfaces: -** -** sqlite3_client_open -** sqlite3_client_prepare -** sqlite3_client_step -** sqlite3_client_reset -** sqlite3_client_finalize -** sqlite3_client_close -** -** These interfaces work exactly like the standard core SQLite interfaces -** having the same names without the "_client_" infix. Many other SQLite -** interfaces can be used directly without having to send messages to the -** server as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined. -** The following interfaces fall into this second category: -** -** sqlite3_bind_* -** sqlite3_changes -** sqlite3_clear_bindings -** sqlite3_column_* -** sqlite3_complete -** sqlite3_create_collation -** sqlite3_create_function -** sqlite3_data_count -** sqlite3_db_handle -** sqlite3_errcode -** sqlite3_errmsg -** sqlite3_last_insert_rowid -** sqlite3_total_changes -** sqlite3_transfer_bindings -** -** A single SQLite connection (an sqlite3* object) or an SQLite statement -** (an sqlite3_stmt* object) should only be passed to a single interface -** function at a time. The connections and statements can be passed from -** any thread to any of the functions listed in the second group above as -** long as the same connection is not in use by two threads at once and -** as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined. Additional -** information about the SQLITE_ENABLE_MEMORY_MANAGEMENT constraint is -** below. -** -** The busy handler for all database connections should remain turned -** off. That means that any lock contention will cause the associated -** sqlite3_client_step() call to return immediately with an SQLITE_BUSY -** error code. If a busy handler is enabled and lock contention occurs, -** then the entire server thread will block. This will cause not only -** the requesting client to block but every other database client as -** well. It is possible to enhance the code below so that lock -** contention will cause the message to be placed back on the top of -** the queue to be tried again later. But such enhanced processing is -** not included here, in order to keep the example simple. -** -** This example code assumes the use of pthreads. Pthreads -** implementations are available for windows. (See, for example -** http://sourceware.org/pthreads-win32/announcement.html.) Or, you -** can translate the locking and thread synchronization code to use -** windows primitives easily enough. The details are left as an -** exercise to the reader. -** -**** Restrictions Associated With SQLITE_ENABLE_MEMORY_MANAGEMENT **** -** -** If you compile with SQLITE_ENABLE_MEMORY_MANAGEMENT defined, then -** SQLite includes code that tracks how much memory is being used by -** each thread. These memory counts can become confused if memory -** is allocated by one thread and then freed by another. For that -** reason, when SQLITE_ENABLE_MEMORY_MANAGEMENT is used, all operations -** that might allocate or free memory should be performanced in the same -** thread that originally created the database connection. In that case, -** many of the operations that are listed above as safe to be performed -** in separate threads would need to be sent over to the server to be -** done there. If SQLITE_ENABLE_MEMORY_MANAGEMENT is defined, then -** the following functions can be used safely from different threads -** without messing up the allocation counts: -** -** sqlite3_bind_parameter_name -** sqlite3_bind_parameter_index -** sqlite3_changes -** sqlite3_column_blob -** sqlite3_column_count -** sqlite3_complete -** sqlite3_data_count -** sqlite3_db_handle -** sqlite3_errcode -** sqlite3_errmsg -** sqlite3_last_insert_rowid -** sqlite3_total_changes -** -** The remaining functions are not thread-safe when memory management -** is enabled. So one would have to define some new interface routines -** along the following lines: -** -** sqlite3_client_bind_* -** sqlite3_client_clear_bindings -** sqlite3_client_column_* -** sqlite3_client_create_collation -** sqlite3_client_create_function -** sqlite3_client_transfer_bindings -** -** The example code in this file is intended for use with memory -** management turned off. So the implementation of these additional -** client interfaces is left as an exercise to the reader. -** -** It may seem surprising to the reader that the list of safe functions -** above does not include things like sqlite3_bind_int() or -** sqlite3_column_int(). But those routines might, in fact, allocate -** or deallocate memory. In the case of sqlite3_bind_int(), if the -** parameter was previously bound to a string that string might need -** to be deallocated before the new integer value is inserted. In -** the case of sqlite3_column_int(), the value of the column might be -** a UTF-16 string which will need to be converted to UTF-8 then into -** an integer. -*/ - -/* Include this to get the definition of SQLITE_THREADSAFE, in the -** case that default values are used. -*/ -#include "sqliteInt.h" - -/* -** Only compile the code in this file on UNIX with a SQLITE_THREADSAFE build -** and only if the SQLITE_SERVER macro is defined. -*/ -#if defined(SQLITE_SERVER) && !defined(SQLITE_OMIT_SHARED_CACHE) -#if defined(OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE - -/* -** We require only pthreads and the public interface of SQLite. -*/ -#include -#include "sqlite3.h" - -/* -** Messages are passed from client to server and back again as -** instances of the following structure. -*/ -typedef struct SqlMessage SqlMessage; -struct SqlMessage { - int op; /* Opcode for the message */ - sqlite3 *pDb; /* The SQLite connection */ - sqlite3_stmt *pStmt; /* A specific statement */ - int errCode; /* Error code returned */ - const char *zIn; /* Input filename or SQL statement */ - int nByte; /* Size of the zIn parameter for prepare() */ - const char *zOut; /* Tail of the SQL statement */ - SqlMessage *pNext; /* Next message in the queue */ - SqlMessage *pPrev; /* Previous message in the queue */ - pthread_mutex_t clientMutex; /* Hold this mutex to access the message */ - pthread_cond_t clientWakeup; /* Signal to wake up the client */ -}; - -/* -** Legal values for SqlMessage.op -*/ -#define MSG_Open 1 /* sqlite3_open(zIn, &pDb) */ -#define MSG_Prepare 2 /* sqlite3_prepare(pDb, zIn, nByte, &pStmt, &zOut) */ -#define MSG_Step 3 /* sqlite3_step(pStmt) */ -#define MSG_Reset 4 /* sqlite3_reset(pStmt) */ -#define MSG_Finalize 5 /* sqlite3_finalize(pStmt) */ -#define MSG_Close 6 /* sqlite3_close(pDb) */ -#define MSG_Done 7 /* Server has finished with this message */ - - -/* -** State information about the server is stored in a static variable -** named "g" as follows: -*/ -static struct ServerState { - pthread_mutex_t queueMutex; /* Hold this mutex to access the msg queue */ - pthread_mutex_t serverMutex; /* Held by the server while it is running */ - pthread_cond_t serverWakeup; /* Signal this condvar to wake up the server */ - volatile int serverHalt; /* Server halts itself when true */ - SqlMessage *pQueueHead; /* Head of the message queue */ - SqlMessage *pQueueTail; /* Tail of the message queue */ -} g = { - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_COND_INITIALIZER, -}; - -/* -** Send a message to the server. Block until we get a reply. -** -** The mutex and condition variable in the message are uninitialized -** when this routine is called. This routine takes care of -** initializing them and destroying them when it has finished. -*/ -static void sendToServer(SqlMessage *pMsg){ - /* Initialize the mutex and condition variable on the message - */ - pthread_mutex_init(&pMsg->clientMutex, 0); - pthread_cond_init(&pMsg->clientWakeup, 0); - - /* Add the message to the head of the server's message queue. - */ - pthread_mutex_lock(&g.queueMutex); - pMsg->pNext = g.pQueueHead; - if( g.pQueueHead==0 ){ - g.pQueueTail = pMsg; - }else{ - g.pQueueHead->pPrev = pMsg; - } - pMsg->pPrev = 0; - g.pQueueHead = pMsg; - pthread_mutex_unlock(&g.queueMutex); - - /* Signal the server that the new message has be queued, then - ** block waiting for the server to process the message. - */ - pthread_mutex_lock(&pMsg->clientMutex); - pthread_cond_signal(&g.serverWakeup); - while( pMsg->op!=MSG_Done ){ - pthread_cond_wait(&pMsg->clientWakeup, &pMsg->clientMutex); - } - pthread_mutex_unlock(&pMsg->clientMutex); - - /* Destroy the mutex and condition variable of the message. - */ - pthread_mutex_destroy(&pMsg->clientMutex); - pthread_cond_destroy(&pMsg->clientWakeup); -} - -/* -** The following 6 routines are client-side implementations of the -** core SQLite interfaces: -** -** sqlite3_open -** sqlite3_prepare -** sqlite3_step -** sqlite3_reset -** sqlite3_finalize -** sqlite3_close -** -** Clients should use the following client-side routines instead of -** the core routines above. -** -** sqlite3_client_open -** sqlite3_client_prepare -** sqlite3_client_step -** sqlite3_client_reset -** sqlite3_client_finalize -** sqlite3_client_close -** -** Each of these routines creates a message for the desired operation, -** sends that message to the server, waits for the server to process -** then message and return a response. -*/ -int sqlite3_client_open(const char *zDatabaseName, sqlite3 **ppDb){ - SqlMessage msg; - msg.op = MSG_Open; - msg.zIn = zDatabaseName; - sendToServer(&msg); - *ppDb = msg.pDb; - return msg.errCode; -} -int sqlite3_client_prepare( - sqlite3 *pDb, - const char *zSql, - int nByte, - sqlite3_stmt **ppStmt, - const char **pzTail -){ - SqlMessage msg; - msg.op = MSG_Prepare; - msg.pDb = pDb; - msg.zIn = zSql; - msg.nByte = nByte; - sendToServer(&msg); - *ppStmt = msg.pStmt; - if( pzTail ) *pzTail = msg.zOut; - return msg.errCode; -} -int sqlite3_client_step(sqlite3_stmt *pStmt){ - SqlMessage msg; - msg.op = MSG_Step; - msg.pStmt = pStmt; - sendToServer(&msg); - return msg.errCode; -} -int sqlite3_client_reset(sqlite3_stmt *pStmt){ - SqlMessage msg; - msg.op = MSG_Reset; - msg.pStmt = pStmt; - sendToServer(&msg); - return msg.errCode; -} -int sqlite3_client_finalize(sqlite3_stmt *pStmt){ - SqlMessage msg; - msg.op = MSG_Finalize; - msg.pStmt = pStmt; - sendToServer(&msg); - return msg.errCode; -} -int sqlite3_client_close(sqlite3 *pDb){ - SqlMessage msg; - msg.op = MSG_Close; - msg.pDb = pDb; - sendToServer(&msg); - return msg.errCode; -} - -/* -** This routine implements the server. To start the server, first -** make sure g.serverHalt is false, then create a new detached thread -** on this procedure. See the sqlite3_server_start() routine below -** for an example. This procedure loops until g.serverHalt becomes -** true. -*/ -void *sqlite3_server(void *NotUsed){ - if( pthread_mutex_trylock(&g.serverMutex) ){ - return 0; /* Another server is already running */ - } - sqlite3_enable_shared_cache(1); - while( !g.serverHalt ){ - SqlMessage *pMsg; - - /* Remove the last message from the message queue. - */ - pthread_mutex_lock(&g.queueMutex); - while( g.pQueueTail==0 && g.serverHalt==0 ){ - pthread_cond_wait(&g.serverWakeup, &g.queueMutex); - } - pMsg = g.pQueueTail; - if( pMsg ){ - if( pMsg->pPrev ){ - pMsg->pPrev->pNext = 0; - }else{ - g.pQueueHead = 0; - } - g.pQueueTail = pMsg->pPrev; - } - pthread_mutex_unlock(&g.queueMutex); - if( pMsg==0 ) break; - - /* Process the message just removed - */ - pthread_mutex_lock(&pMsg->clientMutex); - switch( pMsg->op ){ - case MSG_Open: { - pMsg->errCode = sqlite3_open(pMsg->zIn, &pMsg->pDb); - break; - } - case MSG_Prepare: { - pMsg->errCode = sqlite3_prepare(pMsg->pDb, pMsg->zIn, pMsg->nByte, - &pMsg->pStmt, &pMsg->zOut); - break; - } - case MSG_Step: { - pMsg->errCode = sqlite3_step(pMsg->pStmt); - break; - } - case MSG_Reset: { - pMsg->errCode = sqlite3_reset(pMsg->pStmt); - break; - } - case MSG_Finalize: { - pMsg->errCode = sqlite3_finalize(pMsg->pStmt); - break; - } - case MSG_Close: { - pMsg->errCode = sqlite3_close(pMsg->pDb); - break; - } - } - - /* Signal the client that the message has been processed. - */ - pMsg->op = MSG_Done; - pthread_mutex_unlock(&pMsg->clientMutex); - pthread_cond_signal(&pMsg->clientWakeup); - } - sqlite3_thread_cleanup(); - pthread_mutex_unlock(&g.serverMutex); - return 0; -} - -/* -** Start a server thread if one is not already running. If there -** is aleady a server thread running, the new thread will quickly -** die and this routine is effectively a no-op. -*/ -void sqlite3_server_start(void){ - pthread_t x; - int rc; - g.serverHalt = 0; - rc = pthread_create(&x, 0, sqlite3_server, 0); - if( rc==0 ){ - pthread_detach(x); - } -} - -/* -** If a server thread is running, then stop it. If no server is -** running, this routine is effectively a no-op. -** -** This routine waits until the server has actually stopped before -** returning. -*/ -void sqlite3_server_stop(void){ - g.serverHalt = 1; - pthread_cond_broadcast(&g.serverWakeup); - pthread_mutex_lock(&g.serverMutex); - pthread_mutex_unlock(&g.serverMutex); -} - -#endif /* defined(OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE */ -#endif /* defined(SQLITE_SERVER) */ -- cgit v1.1