⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_server.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 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(SQLITE_OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE */#endif /* defined(SQLITE_SERVER) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -