|
|
|
|
|
|
| Author |
Message |
Chris Newcombe *nix forums beginner
Joined: 01 Mar 2005
Posts: 5
|
Posted: Tue Mar 01, 2005 2:08 am Post subject:
Re: Interrupting Blocking consume()
|
|
|
Arun Kumar wrote:
| Quote: | What is the suggested mechanism to interrupt a
blocking consume() call ?
BTW, the consume() call is wrapped around a transaction, and
the transaction object is available to the application.
Any pointers/examples/suggestions on how to acheive this using
the Java API are welcome.
|
Well, I've only done this with the C++ API, but the calls should be the
same.
In the 'control' thread (i.e. that wants to unblock the 'consume'
thread)
a. Create a DB_LOCKREQ, with all members set to 0, apart from
LockReq.op, which should be set to DB_LOCK_TIMEOUT;
b. Call DbEnv->lock_vec(), passing the locker-id of the transaction
that is running the consume. This is obtained via the DbTxn::id()
method; http://www.sleepycat.com/docs/api_cxx/txn_id.html.
Obviously you need to code your own thread-safe mechanism to ensure
that id's are safely passed to/from the control thread. (Note that
DbTxn objects are *not* safe for use by multiple threads
simultaneously.) I used a pair of functions to register the id before
the call to consume, and to unregister it afterwards. (Don't forget to
unregister it even if consume throws an exception. Of course, the
container of registered ids will need to be protected by a mutex.
Of course there is still an unavoidable race-condition here. If,
after you get the id() and start to call lock_vec, the consume() call
returns and the transaction is commited or aborted, your lock_vec call
will find that it has an invalid (expired) transaction id. Sleepycat
told me that this is safe; lock_vec will return (or throw) an 'invalid
transaction id' error in this case, but will not crash.
Other arguments to lock_vec are; the address of the LockReq object
created in step (a), and pass 1 as the 'nlist' argument of course. You
can pass NULL as the 'elistp' argument.
c. Sleepycat's docs state that "if the database environment has NOT
configured automatic deadlock detection, the transaction will timeout
the next time deadlock detection is performed."
However, in an early version of v4.2 I found that statement wasn't true
-- i.e. the transactions don't timeout unless you explicitly invoke the
deadlock detector. If that is still the case with the version you are
using, you should manually call the deadlock detector.
int num_terminated_locks;
DbEnv->lock_detect( 0, DB_LOCK_DEFAULT, &num_terminated_locks );
The consume() call should now return a "lock timed out" exception.
IIRC, this use of lock_vec was broken in v4.1. So make sure you are
using at least v4.2.
I hope this helps,
Chris Newcombe |
|
| Back to top |
|
 |
Arun Kumar *nix forums beginner
Joined: 06 May 2005
Posts: 3
|
Posted: Mon Feb 28, 2005 1:55 pm Post subject:
Interrupting Blocking consume()
|
|
|
Hi All,
What is the suggested mechanism to interrupt a
blocking consume() call ? I am working on a mult-threaded java
application, in the app I have a thread that reads from a
Queue database and blocks on the consume() call when there are no
records.
When the application needs to stop this thread, I need to
intterupt the blocking consume() call, so that I can fall through
the rest of the clean up code and stop the thread cleanly.
BTW, the consume() call is wrapped around a transaction, and
the transaction object is available to the application.
Any pointers/examples/suggestions on how to acheive this using
the Java API are welcome.
Thanks in Advance,
Arun |
|
| Back to top |
|
 |
Google
|
|
| Back to top |
|
 |
|
|
The time now is Thu Jan 08, 2009 5:05 am | All times are GMT
|
|
Mobile Phone | Xbox Mod Chip | Internet Advertising | Florence apartments | Libros de historia
|
|
Copyright © 2004-2005 DeniX Solutions SRL
|
|
|
|
Other DeniX Solutions sites:
Unix/Linux blog |
electronics forum |
medicine forum |
science forum |
|
|
Privacy Policy
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|