Hello,

Here follows, my Async IO implementation (at the moment, I just have tested the
Win32 part. I will test soon the pthreads part).

The main thread creates a worker thread (in charge of running the
sqlite3async_run function).

In "Build options/compiler/defines", it seems that the following is working:
SQLITE_THREADSAFE=0


--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
#include "sqlite3async.h"

#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) ||
defined(__MINGW32__) || defined(__BORLANDC__)
#include <windows.h>
#else
#include <pthread.h>
#endif


static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  NotUsed=0;
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i]: "NULL");
  }
  printf("\n");
  return 0;
}

struct s_async_sqlite3 {
    sqlite3 *pdb;
#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) ||
defined(__MINGW32__) || defined(__BORLANDC__)
    HANDLE hThread;
#else
    pthread_t th;
#endif
};

typedef struct s_async_sqlite3 async_sqlite3;

int initSQLite(char *sDatabaseFile, int lock, async_sqlite3 *pasyncsql){

    /* Initialize async IO for sqlite
        - The current default VFS is used for IO
        - the asynchronous IO VFS is registered as the default VFS for all
SQLite database connections within the process.
    */
    if(sqlite3async_initialize(NULL, 1) != SQLITE_OK){
        /* display some error */
        return 0;
    }

    /* The sqlite3async_run will never stop
    */
    if(sqlite3async_control(SQLITEASYNC_HALT, SQLITEASYNC_HALT_NEVER) != 
SQLITE_OK){
        /* display some error */
        return 0;
    }

    /* Lock are used (resp. not used)
        - locks allow multiple accesses from several processes without
corrupting the database but may impact the throughput
    */
    if(sqlite3async_control(SQLITEASYNC_LOCKFILES, lock) != SQLITE_OK){
        /* display some error */
        return 0;
    }

    if(sqlite3_threadsafe()){
        printf("Thread Safe\n");
    } else {
        printf("Not Thread Safe\n");
    }

#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) ||
defined(__MINGW32__) || defined(__BORLANDC__)
    /* Create a thread using Windows API */
    if(! (pasyncsql->hThread = CreateThread(
            NULL,                   // default security attributes
            0,                      // use default stack size
            (LPTHREAD_START_ROUTINE)sqlite3async_run,       // thread function 
name
            NULL,                   // argument to thread function
            0,                      // use default creation flags
            NULL))){                 // returns the thread identifier
        return 0;
    }

#else
    /* Create a thread using pthreads API - Not tested at the moment */
    if(pthread_create(&pasyncsql->th, NULL, sqlite3async_run, NULL)){
        return 0;
    }
#endif

    /* Database must exist */
    if(sqlite3_open_v2(sDatabaseFile, &pasyncsql->pdb, SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK){
        /* display some error */
        fprintf(stderr, "Can't open database: %s\n",
sqlite3_errmsg(pasyncsql->pdb));
        sqlite3_close(pasyncsql->pdb);
        return 0;
    }
    return 1;
}

void shutdownSQLite(async_sqlite3 *pasyncsql, int force){
    /* force <> 0 : HALT SQLITE NOW
       force = 0  : HALT WHEN IDLE */
    sqlite3async_control(SQLITEASYNC_HALT, force ? SQLITEASYNC_HALT_NOW :
SQLITEASYNC_HALT_IDLE);

#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) ||
defined(__MINGW32__) || defined(__BORLANDC__)
    /* Wait for the sqlite3async_run thread completion using Windows API */
    if(pasyncsql->hThread){
        WaitForSingleObject(pasyncsql->hThread, INFINITE);
        CloseHandle(pasyncsql->hThread);
        pasyncsql->hThread = NULL;
    }
#else
    /* Wait for the sqlite3async_run thread completion using pthreads API */
    if(pasyncsql->th){
        pthread_join(pasyncsql->th, NULL);
        pasyncsql->th = NULL;
    }
#endif

    /* close sqlite database */
    if(pasyncsql->pdb){
        sqlite3_close(pasyncsql->pdb);
        pasyncsql->pdb = NULL;
    }

    /* shutdown async IO */
    sqlite3async_shutdown();
}


int main(int argc, char **argv){
  async_sqlite3 asyncsql;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    exit(1);
  }

    if(!initSQLite(argv[1], 1, &asyncsql)){
        exit(1);
    }

  rc = sqlite3_exec(asyncsql.pdb, argv[2], callback, 0, &zErrMsg);
  if( rc != SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    /* This will free zErrMsg if assigned */
    if (zErrMsg)
       free(zErrMsg);
  } else {
    printf("ok\n");
  }

  shutdownSQLite(&asyncsql, 0);
  return 0;
}



_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to