Re: PRLock and PRRWLock

Wan-Teh Chang <[email protected]> Thu, 22 Jan 2009 10:13:35 -0800
Newsgroups gmane.comp.mozilla.devel.nspr
Message-ID <[email protected]>
On Thu, Jan 22, 2009 at 6:07 AM, Sabyasachi Ruj <[email protected]> wrote:
> Sorry, if I am re-posting my question, I posted earlier from Google groups,
> but am not able to see the message even after half an hour.
>
> I am using these locks: PRLock and PRRWLock.
> I want a timeout in the lock functions.
> So, it will wait for 45 seconds, and if it is not able to acquire a lock
> within that time, the call should come out with an error.
>
> Then we can report error to the user within 45 seconds.
>
> How can I do it?
>
> Actually I am doing some SQLite operation inside a lock, and sometimes that
> take long time to complete, if the database is large (~1.9 GB).
> I want to come up with error to the user that time, if acquiring lock fails.
> Please help.

The lock functions for PRLock and PRRWLock don't have
a timeout parameter.  You are not supposed to hold a
PRLock or PRRWLock for a very long time.

You can build any synchronization you want using PRLock
and PRCondVar.  It may take some practice to master the
use of PRCondVar, but PRLock and PRCondVar are
general primitives for building higher-level synchronization.
You can wait on a PRCondVar with a timeout.

You should be able to do what you want with something
like this:

PRLock *lock = PR_NewLock();
PRCondVar *cv = PR_NewCondVar(lock);
PRBool in_use = PR_FALSE;
PRIntervalTime time_before;
PRIntervalTime elapsed_time;
PRIntervalTime timeout = PR_SecondsToIntervalTime(45);
PRBool got_lock;

got_lock = PR_FALSE;
PR_Lock(lock);
if (in_use) {
    time_before = PR_IntervalNow();
    do {
        PR_WaitCondVar(cv, timeout);
        elapsed_time = PR_IntervalNow() - time_before;
    } while (in_use && elapsed_time < timeout);
}
if (!in_use) {
  in_use = PR_TRUE;
  got_lock = PR_TRUE;
}
PR_Unlock(lock);

if (got_lock) {
    Do SQLite operation
}

PR_Lock(lock);
in_use = PR_FALSE;
PR_NotifyCondVar(cv);
PR_Unlock(lock);

Wan-Teh