Hi Ranchers,
my interface uses lock cookies. In the specs I have the following sentence:
"Any attempt to lock a resource that is already locked should cause the current
thread to give up the CPU, consuming no CPU cycles until the desired resource becomes available."
What I understand by this (especially the "give up the CPU until resource is available") is that I need code like this one:
and in unlock:
However, there is a possibility of a deadlock - if the same client tries to lock the same record twice, sequentiallly: it locks first, then it attempts to lock second time, and the record is locked,(by it!) so it calls await() on the condition. Other clients don't have the lock so cannot help, and if by any chance all other clients want to lock the same record, there is a global distributed deadlock - not nice.
I think I will go for RMI simply because I want to learn it (I use JDK 5 Locks for the very same reason, and I think I will state it explicitly in choices.txt). I am not sure, but I think it is possible that the same thread might be reused by different requests, so by different clients. This prevents me from having code that checks if the record was locked by the same thread as attempts to lock it now to return if the same thread wants to lock the same record - firstly because I will never be sure that the same client / different request will use the same thread (most likely not), and secondly (as mentioned) a different client might use the same thread from the pool or whatever.
What do you say? How can I make it better? Maybe I didn't understand the specs?
What about the awainUninterruptibly() call? Do you think it is good here? I don't have to catch InterruptedException this way - how else do you suggest to deal with it?
Something about my design - the DB uses a single Lock (for simplicity, the specs wants a junior to understand the code and I don't know where a junior draws the line
) to synchronize the reads / writes to the (RandomAccessFile) database. Also, the same lock is used to create a Condition lockTaken (mentioned in the code snippets above) and it is used when LockManager is created. Every LockManager method is called with the Lock acquired, so using the lockTaken Condition is safe. Now, the update() / delete() in DB methods require the lock cookie to match, and it is checked again using LockManager, but it is simple code, no Condition magic there. lock() / unlock() pretty much look like shown above - with some exception handling.
One more thing - the unlock() method specs say:
"Releases the lock on a record. Cookie must be the cookie returned when the record was locked; otherwise throws SecurityException."
I throw this exc when it is attempted to unlock() a record that is not locked. Do you think it is OK? It seems like a security vulnerability to me - after all,
you should only unlock() if you know you locked the record and have the cookie to authorize the action.
Do you think it is OK? What are your suggestions?
Regards,
Raf