Hi Dan,

thank you!

Yes! I was not aware that it is wrong to redo a step
when it previously returned the LOCKED state.
That was the reason for the (correct) MISSUSE return on
the 2nd attempt.

I think this is the main difference in my case between
shared cache on/off: Without shared cache I never
get this lock state and it just does the BUSY handling correctly.

I'll change my locking handling accordingly, seems to be a problem
of the very first step after a prepare, so that's should to be easy
to reset...


Thanks again for your feedback

Marcus

Dan wrote:
> On Mar 5, 2009, at 9:57 PM, Marcus Grimm wrote:
> 
>> Hi again,
>>
>> I did a little test program that simulates the multi threading
>> issue to understand better why I get a MISSUSE error even
>> when sqlite_prepare returns no error.
>> The test program will printout some errors on the console
>> and exits in that case. If I don't use the shared cache it
>> runs endless without any problem.
>>
>> The code is to long to be placed here, but I would be very happy
>> if somebody could take a look. I've put it on a web server to  
>> download:
>>
>> http://www.exomio.de/sqlitethreadtest.c
>>
>> I'm using MS Visual Studio 2008, the program is started within a
>> dosbox to see the error output. Using it on my dual core PC
>> it allmost immediately stops with the missuse error, ....but why?
> 
>      do
>      {
>          rc = sqlite3_step(hs);
> 
>          if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) )
>          {
>              Sleep(SQLTM_TIME);
> 
>              n++;
>          }
>      }while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc ==  
> SQLITE_LOCKED)));
> 
> If sqlite3_step() returns SQLITE_BUSY or SQLITE_LOCKED, you need to
> reset the statement before trying the sqlite3_step() again.
> 
> Dan.
> 
> 
> 
> 
>> Thanks you
>>
>> kind regards
>>
>> Marcus Grimm
>>
>> Marcus Grimm wrote:
>>> Hi Ken,
>>>
>>> yes, I do check the return values also for the
>>> sqlite3_prepare_v2 call. This is allways
>>> successful, the first sqlite_step call right after
>>> this one returns the magic MISSUSE.
>>>
>>> Yes, I also tried to call sqlite_reset right
>>> after this first error and in this case
>>> sqlite_reset return the LOCK state. I didn't
>>> yet go on to handle this...
>>>
>>> I can't post the code of the original implementation here,
>>> but also for my debugging and tests I'll produce
>>> a simplified test application. Just to see if that
>>> can be used to reproduce the effect. If that one runs
>>> without any problem, it's my fault, if not: I'll post
>>> it here for further discussions... ;)
>>>
>>> Thanks for your feedback
>>>
>>> Marcus
>>>
>>>
>>>> Marcus,
>>>>
>>>> I'm not sure if this will help or not...
>>>>
>>>> But I noticed your sample code does not test the return value from  
>>>> the
>>>> sqlite3_prepare_v2 call. Could the code be entering the do  loop  
>>>> when an
>>>> error was returned from prepare?
>>>>
>>>> Just an idea.
>>>>
>>>> Have you tried the reset call as DRH had suggested?
>>>> Your prior post indicated you had more code and another loop. Can  
>>>> you post
>>>> the full code for both loops?
>>>>
>>>> HTH
>>>>
>>>>
>>>>
>>>> --- On Wed, 3/4/09, Marcus Grimm <mgr...@medcom-online.de> wrote:
>>>>
>>>>> From: Marcus Grimm <mgr...@medcom-online.de>
>>>>> Subject: Re: [sqlite] shared cache and SQLITE_MISUSE on  
>>>>> sqlite3_step()
>>>>> To: kennethinbox-sql...@yahoo.com, "General Discussion of SQLite
>>>>> Database" <sqlite-users@sqlite.org>
>>>>> Date: Wednesday, March 4, 2009, 4:31 PM
>>>>> Ken,
>>>>>
>>>>> you are of course right that it needs some checks
>>>>> for locks and busy states. I left that out to
>>>>> simplify the code given below. My original code
>>>>> checks that and it usually works quite well.
>>>>> that's basically the reason why I was puzzled
>>>>> by the randomly MISUSE results after I added the shared
>>>>> cache.
>>>>>
>>>>> I'm not yet finished with my debugging since it is a
>>>>> multithreading/collision issue - ugly to trace.
>>>>>
>>>>> My feeling is that it is related to the condition when
>>>>> one thread is attempting or holding an exclusive lock
>>>>> while another thread is just doing an sqlite_step (read
>>>>> only)
>>>>> on an allready created statement. Both threads use their
>>>>> own
>>>>> DB connections. For example: when I do a sqlite_reset
>>>>> right after sqlite_step returns SQLITE_MISUSE, as Richard
>>>>> suggest,
>>>>> I get immediately a SQLITE_LOCK return code from
>>>>> sqlite_reset in this case. Why I didn't get that before
>>>>> or
>>>>> from the sqlite_prepare ?
>>>>>
>>>>> Anyway, I'm going on to workaround this.... ALso I
>>>>> would like
>>>>> to mention once more that it is only during an artificial
>>>>> stress
>>>>> test, mainly to verify my implementation. Under normal
>>>>> usercondition it is very unlikely to happend and sqlite
>>>>> works perfect as expected.
>>>>>
>>>>> Thanks
>>>>>
>>>>> Marcus
>>>>>
>>>>>> Marcus,
>>>>>>
>>>>>> You might want to also add some checks in for
>>>>> sqlite_busy as on the result
>>>>>> of the prepare and the first call to sqlite_step.
>>>>>>
>>>>>>
>>>>>> On the inner loop test for the most common case first
>>>>> (SQLITE_ROW) then
>>>>>> test for errors... Slight performance improvement...
>>>>>>
>>>>>>
>>>>>> --- On Wed, 3/4/09, Marcus Grimm
>>>>> <mgr...@medcom-online.de> wrote:
>>>>>>> From: Marcus Grimm <mgr...@medcom-online.de>
>>>>>>> Subject: Re: [sqlite] shared cache and
>>>>> SQLITE_MISUSE on sqlite3_step()
>>>>>>> To: "General Discussion of SQLite
>>>>> Database" <sqlite-users@sqlite.org>
>>>>>>> Date: Wednesday, March 4, 2009, 10:25 AM
>>>>>>> Richard, thanks again for the feedback.
>>>>>>>
>>>>>>> However, I don't see how it can happend that
>>>>> the
>>>>>>> statement
>>>>>>> is completed internally without returning
>>>>> SQLITE_DONE.
>>>>>>> In the particular code of the "reading
>>>>> thread" I
>>>>>>> do something like:
>>>>>>>
>>>>>>> --
>>>>>>> sqlite3_prepare_v2(db, "SELECT * FROM
>>>>> TableA",
>>>>>>> -1, &stmt, 0);
>>>>>>> /** step throu table result **/
>>>>>>> do
>>>>>>> {
>>>>>>>   rc = sqlite3_step(stmt);
>>>>>>>   if( rc == SQLITE_MISUSE )
>>>>>>>   {  fprintf(stderr, "ERROR...\n");
>>>>> break; }
>>>>>>>   else
>>>>>>>   if( rc == SQLITE_ROW )
>>>>>>>     read_data_etc();
>>>>>>>   else
>>>>>>>     break;
>>>>>>> }while( rc != SQLITE_DONE );
>>>>>>>
>>>>>>> sqlite3_finalize(stmt);
>>>>>>> --
>>>>>>>
>>>>>>> The prepare statement pointer is defined locally
>>>>> and no
>>>>>>> other
>>>>>>> thread can access it, except sqlite internal
>>>>> maybe.
>>>>>>> To me it looks that in case a parallel thread is
>>>>> inserting
>>>>>>> or
>>>>>>> updating data, the above loop is somehow affected
>>>>> and
>>>>>>> returns the
>>>>>>> MISUSE.
>>>>>>>
>>>>>>> Your reply so far indicates either a bug on my
>>>>> side or a
>>>>>>> missusage.
>>>>>>> I'll go on and try to find the reason why the
>>>>> magic
>>>>>>> number is resetted
>>>>>>> without knowing from calling functions.
>>>>>>>
>>>>>>> calling sqlite3_reset in these cases is difficult
>>>>> for me
>>>>>>> since it might
>>>>>>> not be the first step and previous data is
>>>>> allready in use
>>>>>>> in the upper loop.
>>>>>>> But maybe an option for the very first step if
>>>>> that
>>>>>>> fails... hm... I'll try that.
>>>>>>>
>>>>>>>
>>>>>>> Thanks again
>>>>>>>
>>>>>>> kind regards
>>>>>>>
>>>>>>> Marcus Grimm
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> D. Richard Hipp wrote:
>>>>>>>> On Mar 4, 2009, at 9:35 AM, Marcus Grimm
>>>>> wrote:
>>>>>>>>> hi,
>>>>>>>>>
>>>>>>>>> OK, the value of p->magic is 519C2973
>>>>>>> (VDBE_MAGIC_HALT)
>>>>>>>> That means the prepared statement has run to
>>>>>>> completion and needs to
>>>>>>>> be reset using sqlite3_reset() before you
>>>>> continue.
>>>>>>>> D. Richard Hipp
>>>>>>>> d...@hwaci.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
>>>>>> _______________________________________________
>>>>>> 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
>>>
>> -- 
>> Marcus Grimm, MedCom GmbH Darmstadt, Rundeturmstr. 12, 64283 Darmstadt
>> Tel: +49(0)6151-95147-10
>> Fax: +49(0)6151-95147-20
>> --------------------------------------------------
>> MedCom slogans of the month:
>> "Vacation ? -- Every day at MedCom is a paid vacation!"
>> "Friday I have monday in my mind."
>> "MedCom -- Every week a vacation, every day an event, every hour a  
>> cliffhanger,
>>            every minute a climax."
>> "Damned, it's weekend again!"
>> _______________________________________________
>> 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
> 

-- 
Marcus Grimm, MedCom GmbH Darmstadt, Rundeturmstr. 12, 64283 Darmstadt
Tel: +49(0)6151-95147-10
Fax: +49(0)6151-95147-20
--------------------------------------------------
MedCom slogans of the month:
"Vacation ? -- Every day at MedCom is a paid vacation!"
"Friday I have monday in my mind."
"MedCom -- Every week a vacation, every day an event, every hour a cliffhanger,
            every minute a climax."
"Damned, it's weekend again!"
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to