Thank you very much for your post

Just after I post the last code I know the concept of "reentrant" and
"thread-safety".

And you should notice the wrong usage of printf() in signal handle func. ^_^

So I re-writed the code and re-test. And the problem is still in someplace.
So I re-post the question.

Again, I appreciate your answer, :)



Pavel Ivanov-2 wrote:
> 
> Why do you re-post your code as if it's another question not related
> to previous one (along with the answer)?
> 
>> does it mean that the sqlite3's C-api isn't reentrant or thread-safety?
> 
> If SQLite is compiled with SQLITE_THREADSAFE = 1 or 2 then API is
> thread-safe (with some limitations when it's 2), if SQLITE_THREADSAFE
> = 0 then API is not thread-safe. But in both cases I have a doubt
> about signal-safety and also API is not re-entrant for sure except for
> some specially designed functions.
> 
> Pavel
> 
> On Thu, Jul 9, 2009 at 3:52 AM, liubin liu<7101...@sina.com> wrote:
>>
>> does it mean that the sqlite3's C-api isn't reentrant or thread-safety?
>>
>>
>> ____________________________________________________________
>>
>>
>> #include <stdio.h>      // for printf()
>> #include <signal.h>     // for signal()
>> #include <unistd.h>     // for alarm()
>> #include <stdlib.h>     // for system()
>> #include <pthread.h>    // for pthread_create()
>> #include <sqlite3.h>    // for sqlite3_***
>>
>>
>>
>> sqlite3 *db = NULL;
>>
>> int timer_handle_mark1 = 0;
>> int timer_handle_mark2 = 9;
>>
>>
>>
>> pthread_t trd1;
>>
>> void trd1_task ( void );
>>
>>
>>
>> int sqlite3_helper_create_db (void);
>>
>> int sqlite3_helper_insert_data (void);
>>
>> // psf - prepare, step, finalize
>> int sqlite3_helper_get_data_psf_from_tb1 ( int id );
>>
>> void timer_handler()
>> {
>>    int ret = -1;
>>    int i = 9;
>>
>>    char *query_format2 = "SELECT * FROM ts2 WHERE id=%d;";
>>    char *query_string = NULL;
>>
>>
>>    sqlite3_stmt *p_stmt = NULL;
>>
>>    timer_handle_mark2 = 0;
>>    query_string = sqlite3_mprintf ( query_format2, i%500 );
>>    timer_handle_mark1++;
>>
>>    timer_handle_mark2 = 1;
>>    ret = sqlite3_prepare_v2 ( db, query_string, -1, &p_stmt, NULL );
>>    timer_handle_mark1++;
>>
>>    timer_handle_mark2 = 2;
>>    ret = sqlite3_step ( p_stmt );
>>    timer_handle_mark1++;
>>
>>    //if ( SQLITE_ROW == ret )
>>    //    printf ( "# IN timer_handler(), id: %d, length: %d\n",
>> sqlite3_column_int( p_stmt, 0 ), sqlite3_column_int( p_stmt, 1 ) );
>>
>>    timer_handle_mark2 = 3;
>>    sqlite3_finalize ( p_stmt );
>>    timer_handle_mark1++;
>>
>>
>>    alarm(1);
>> }
>>
>> int inittimer()
>> {
>>    signal ( SIGALRM, timer_handler );
>>    alarm(1);
>>    return 0;
>> }
>>
>> void trd1_task ( void )
>> {
>>    sleep (30);
>>    printf ( "# IN thread 1, after 30 seconds, timer_handle_mark1: %d,
>> timer_handle_mark2: %d\n", timer_handle_mark1, timer_handle_mark2 );
>>    sleep (50);
>>    printf ( "# IN thread 1, after 50 seconds, timer_handle_mark1: %d,
>> timer_handle_mark2: %d\n", timer_handle_mark1, timer_handle_mark2 );
>> }
>>
>>
>>
>> int main ( void )
>> {
>>    int ret = -1;
>>    int i = 0;
>>
>>    ret = pthread_create ( &trd1, 0, (void *)trd1_task, 0 );
>>
>>    ret = sqlite3_open ( "testsignal.db", &db );
>>
>>    sqlite3_helper_create_db ();
>>
>>    sqlite3_helper_insert_data ();
>>
>>    ret = inittimer();
>>
>>    for ( i=0; ; i++ )
>>        ret = sqlite3_helper_get_data_psf_from_tb1 ( i );
>>
>>    ret = sqlite3_close ( db );
>>
>>    system ( "sqlite3 testsignal.db \"SELECT COUNT(*) FROM ts1;\"" );
>>
>>    return 0;
>> }
>>
>>
>> int sqlite3_helper_create_db (void)
>> {
>>    int ret = -1;
>>    char *cr_tb1 = "CREATE TABLE ts1 (id INTEGER PRIMARY KEY, length
>> INTEGER, data CHAR(50));";
>>    char *cr_tb2 = "CREATE TABLE ts2 (id INTEGER PRIMARY KEY, length
>> INTEGER, data CHAR(50));";
>>
>>    ret = sqlite3_exec ( db, cr_tb1, NULL, NULL, NULL );
>>    //printf ( "ret: %d\n", ret );
>>    ret = sqlite3_exec ( db, cr_tb2, NULL, NULL, NULL );
>>    //printf ( "ret: %d\n", ret );
>>    if ( SQLITE_OK == ret )
>>        printf ( "# IN main(), create db file, SUCCESS!\n" );
>>
>>
>>    return 0;
>> }
>>
>>
>> int sqlite3_helper_insert_data (void)
>> {
>>    int ret = -1;
>>    int i = 0;
>>
>>    sqlite3_stmt *p_stmt = NULL;
>>
>>
>>    char *sql_format1 = "INSERT OR REPLACE INTO ts1 (id, length, data)
>> VALUES (%d, %d, %Q);";
>>    char *sql_format2 = "INSERT OR REPLACE INTO ts2 (id, length, data)
>> VALUES (%d, %d, %Q);";
>>    char *sql = NULL;
>>
>>
>>    ret = sqlite3_exec ( db, "BEGIN", NULL, NULL, NULL );
>>    for ( i=0; i<500; i++ )
>>    {
>>        sql = sqlite3_mprintf ( sql_format1, i, i%10,
>> "datadatadatadatadatadatadatadatadatadatadata" );
>>        ret = sqlite3_prepare_v2 ( db, sql, -1, &p_stmt, NULL );
>>        ret = sqlite3_step ( p_stmt );
>>        sqlite3_free ( sql );
>>        ret = sqlite3_finalize ( p_stmt );
>>
>>        sql = sqlite3_mprintf ( sql_format2, i, i%10,
>> "datadatadatadatadatadatadatadatadatadatadata" );
>>        ret = sqlite3_prepare_v2 ( db, sql, -1, &p_stmt, NULL );
>>        ret = sqlite3_step ( p_stmt );
>>        sqlite3_free ( sql );
>>        ret = sqlite3_finalize ( p_stmt );
>>    }
>>    ret = sqlite3_exec ( db, "COMMIT", NULL, NULL, NULL );
>>    if ( SQLITE_OK == ret )
>>        printf ( "# IN main(), insert data, SUCCESS!\n" );
>>
>>    return 0;
>> }
>>
>>
>> int sqlite3_helper_get_data_gt_from_tb1 ( int id )
>> {
>>    int ret = -1;
>>
>>
>>    char *query_format1 = "SELECT * FROM ts1 WHERE id=%d;";
>>    char *query_string = NULL;
>>
>>    char **resultp = NULL;
>>    int row = 0;
>>    int column = 0;
>>    char *errmsg = NULL;
>>    char **tmp_str = NULL;
>>
>>    query_string = sqlite3_mprintf ( query_format1, id%500 );
>>    ret = sqlite3_get_table ( db, query_string, &resultp, &row, &column,
>> &errmsg );
>>    if ( SQLITE_OK == ret )
>>    {
>>        //printf ( "sqlite3_get_table() success!\n" );
>>        tmp_str = resultp + column;
>>        printf ( "# IN main(), id: %d, length: %d\n", atoi(tmp_str[0]),
>> atoi(tmp_str[1]) );
>>    }
>>    sqlite3_free ( query_string );
>>    sqlite3_free_table ( resultp );
>>
>>    return 0;
>> }
>>
>>
>> int sqlite3_helper_get_data_psf_from_tb1 ( int id )
>> {
>>    int ret = -1;
>>
>>    sqlite3_stmt *p_stmt = NULL;
>>
>>
>>    char *query_format1 = "SELECT * FROM ts1 WHERE id=%d;";
>>    char *query_string = NULL;
>>
>>    query_string = sqlite3_mprintf ( query_format1, id%500 );
>>    ret = sqlite3_prepare_v2 ( db, query_string, -1, &p_stmt, NULL );
>>    ret = sqlite3_step ( p_stmt );
>>    //if ( SQLITE_ROW == ret )
>>    //    printf ( "# IN main(), id: %d, length: %d;   timer_handle_mark1:
>> %d\n", sqlite3_column_int( p_stmt, 0 ), sqlite3_column_int( p_stmt, 1 ),
>> timer_handle_mark1 );
>>    sqlite3_finalize ( p_stmt );
>>
>>    return 0;
>> }
>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/is-the-sqlite3%27s-C-api-used-in-thread-safety-mode---or-non-reentrant--tp24405739p24405739.html
>> Sent from the SQLite mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users@sqlite.org
>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> 
> 

-- 
View this message in context: 
http://www.nabble.com/is-the-sqlite3%27s-C-api-used-in-thread-safety-mode---or-non-reentrant--tp24405739p24420186.html
Sent from the SQLite mailing list archive at Nabble.com.

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

Reply via email to