On Mar 5, 2009, at 11:14 PM, Marcus Grimm wrote: > 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.
Technically the SQLITE_BUSY handling is also wrong, for the same reasons. But it's harder to hit a real SQLITE_BUSY than it is to hit an SQLITE_LOCKED in shared-cache mode. > 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... That's correct. An SQLITE_LOCKED or SQLITE_BUSY may only occur on the first call to sqlite3_step(). Dan. > 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 _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users