Transaction API, GenericLock, FileResourceManager

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Transaction API, GenericLock, FileResourceManager

Aaron Hamid
Hi all,

  I suspect I just reimplemented FileResourceManager, because I was not aware of it until recently (despite using the org.apache.commons.transaction.locking package).  Basically I created a hierarchical Node interface, with operations like: children() and read(), which implicitly obtain a readlock; write(), which upgrades to a write lock; and close() which releases the locks.

First, I'm wondering if there is a way to list a directory through the API, which itself requires a read lock, or whether I must explicitly obtain the lock, and then perform the listing externally (which is cumbersome).

Also, I'm curious as to the significance of the "owner" parameter to the lock API.  For instance, I keep lock objects as a member field of Node implementations, using the unique path as a resource id:

public class NodeImpl {
  private ReadWriteLock lock;
  private Node parent;
  public NodeImpl(Node parent, Path path, Store store) {
    lock = new ReadWriteLock(new StorePath(store, path), null);
  }
  public void open() {
    // should I send 'this' as owner?
    lock.acquireRead(this, Long.MAX_VALUE);
  }
  public void openForWriting() {
    // should I send 'this' as owner?
    lock.acquireWrite(this, Long.MAX_VALUE);
  }
  public void write() {
    parent.openForWriting();
    this.openForWriting();
    // .. do some writing ..
  }
  public void close() {
    lock.release();
  }
}

Now...what should the value of the "owner" object be?  Should it naively be the 'this' object?  Or should it be the Thread.currentThread(), or is it completely irrelevant and only for informational purposes?  As you can see, to perform any writing, I must also lock the parent node (for instance, if the write creates a new file...we can't allow reads/listings to be happening).  However, the parent node, in this implementation, will obtain the lock with an owner value of itself.  Now, I intend Node usage to only be single-threaded anyway (the strategy being other threads would obtain a distinct node object, and not share node objects accross threads)...but in any case, is this still legitimate, or should I be obtaining the parent lock with some /other/ value of owner?  If I used distinct owners with that prevent the child not from acquiring the lock, even though it is in its own thread?  The semantics of "owner" don't seem to be very well documented.

Aaron

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Transaction API, GenericLock, FileResourceManager

Oliver Zeigermann
Hi Aaron!

On 6/24/05, Aaron Hamid <[hidden email]> wrote:
> Hi all,
>
>   I suspect I just reimplemented FileResourceManager, because I was not aware of it until recently (despite using the org.apache.commons.transaction.locking package).  Basically I created a hierarchical Node interface, with operations like: children() and read(), which implicitly obtain a readlock; write(), which upgrades to a write lock; and close() which releases the locks.
>
> First, I'm wondering if there is a way to list a directory through the API, which itself requires a read lock, or whether I must explicitly obtain the lock, and then perform the listing externally (which is cumbersome).

The FileResourceManager is more low level than your approach. It does
not have the notion of hierarchichal data and thus no idea of
children.

> Also, I'm curious as to the significance of the "owner" parameter to the lock API.  For instance, I keep lock objects as a member field of Node implementations, using the unique path as a resource id:

The "owner" is whatever object owns, i.e. holds, the lock. This can
e.g. be a thread, a process, a transaction, an application or
whatever. In "normal" Java locking this would be the thread.

> public class NodeImpl {
>   private ReadWriteLock lock;
>   private Node parent;
>   public NodeImpl(Node parent, Path path, Store store) {
>     lock = new ReadWriteLock(new StorePath(store, path), null);
>   }
>   public void open() {
>     // should I send 'this' as owner?
>     lock.acquireRead(this, Long.MAX_VALUE);
>   }
>   public void openForWriting() {
>     // should I send 'this' as owner?
>     lock.acquireWrite(this, Long.MAX_VALUE);
>   }
>   public void write() {
>     parent.openForWriting();
>     this.openForWriting();
>     // .. do some writing ..
>   }
>   public void close() {
>     lock.release();
>   }
> }
>
> Now...what should the value of the "owner" object be?  Should it naively be the 'this' object?  Or should it be the Thread.currentThread(), or is it completely irrelevant and only for informational purposes?  As you can see, to perform any writing, I must also lock the parent node (for instance, if the write creates a new file...we can't allow reads/listings to be happening).  However, the parent node, in this implementation, will obtain the lock with an owner value of itself.  Now, I intend Node usage to only be single-threaded anyway (the strategy being other threads would obtain a distinct node object, and not share node objects accross threads)...but in any case, is this still legitimate, or should I be obtaining the parent lock with some /other/ value of owner?  If I used distinct owners with that prevent the child not from acquiring the lock, even though it is in its own thread?  The semantics of "owner" don't seem to be very well documented.

I thought the notion of an "owner" was rahter obvious. Anyway, if you
have a single threaded application, why use locking?

Oliver

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Transaction] API, GenerickLock, FileResourceManager (was Re: Transaction API, GenericLock, FileResourceManager)

Aaron Hamid
Hi Oliver, thanks for the explanation.  The application itself is not single-threaded.  It is a servlet engine with potentially multiple simultaneous threads.  What is intended to be "single-threaded" is usage of a Node, e.g.:

Node n = store.getPath(path);
List l = n.children();
Node child = (Node) l.get(0);
child.write(...);

(I believe this is similar to JNDI...imagine another request thread doing the same - with different Node instances which refer to the same resource)  I am not intending, for example, the child object to be handed to another thread.  Each Node implementation has its own lock member field, so with respect to parent/child relationships, usage is single-threaded (although clearly re-entrant as children must obtain parent locks).

I will use Thread.currentThread() for the "owner".  I'm not clear as to the utility of non-thread owners...what is the semantics of synchronization if the owners are not threads?  Or is the intention that owners ultimately must be associated with unique threads?

E.g.

ReadWriteLock lock = ...;

String ownerA = "a";
String ownerB = "b";
lock.acquireWrite(ownerA, Long.MAX_VALUE);
lock.acquireWrite(ownerB, Long.MAX_VALUE);

Is the intention that the above statement deadlock? Whereas if the owner was Thread.currentThread (or any 2 identical objects for that matter), I would assume the call we be considered a re-entrant acquisition and not deadlock (?).  I guess I have always thought of the Thread (or some other concurrency construct, such as Process) as the implicit owner in any synchronization scheme.

Aaron

Oliver Zeigermann wrote:

> Hi Aaron!
>
> On 6/24/05, Aaron Hamid <[hidden email]> wrote:
>
>>Hi all,
>>
>>  I suspect I just reimplemented FileResourceManager, because I was not aware of it until recently (despite using the org.apache.commons.transaction.locking package).  Basically I created a hierarchical Node interface, with operations like: children() and read(), which implicitly obtain a readlock; write(), which upgrades to a write lock; and close() which releases the locks.
>>
>>First, I'm wondering if there is a way to list a directory through the API, which itself requires a read lock, or whether I must explicitly obtain the lock, and then perform the listing externally (which is cumbersome).
>
>
> The FileResourceManager is more low level than your approach. It does
> not have the notion of hierarchichal data and thus no idea of
> children.
>
>
>>Also, I'm curious as to the significance of the "owner" parameter to the lock API.  For instance, I keep lock objects as a member field of Node implementations, using the unique path as a resource id:
>
>
> The "owner" is whatever object owns, i.e. holds, the lock. This can
> e.g. be a thread, a process, a transaction, an application or
> whatever. In "normal" Java locking this would be the thread.
>
>
>>public class NodeImpl {
>>  private ReadWriteLock lock;
>>  private Node parent;
>>  public NodeImpl(Node parent, Path path, Store store) {
>>    lock = new ReadWriteLock(new StorePath(store, path), null);
>>  }
>>  public void open() {
>>    // should I send 'this' as owner?
>>    lock.acquireRead(this, Long.MAX_VALUE);
>>  }
>>  public void openForWriting() {
>>    // should I send 'this' as owner?
>>    lock.acquireWrite(this, Long.MAX_VALUE);
>>  }
>>  public void write() {
>>    parent.openForWriting();
>>    this.openForWriting();
>>    // .. do some writing ..
>>  }
>>  public void close() {
>>    lock.release();
>>  }
>>}
>>
>>Now...what should the value of the "owner" object be?  Should it naively be the 'this' object?  Or should it be the Thread.currentThread(), or is it completely irrelevant and only for informational purposes?  As you can see, to perform any writing, I must also lock the parent node (for instance, if the write creates a new file...we can't allow reads/listings to be happening).  However, the parent node, in this implementation, will obtain the lock with an owner value of itself.  Now, I intend Node usage to only be single-threaded anyway (the strategy being other threads would obtain a distinct node object, and not share node objects accross threads)...but in any case, is this still legitimate, or should I be obtaining the parent lock with some /other/ value of owner?  If I used distinct owners with that prevent the child not from acquiring the lock, even though it is in its own thread?  The semantics of "owner" don't seem to be very well documented.
>
>
> I thought the notion of an "owner" was rahter obvious. Anyway, if you
> have a single threaded application, why use locking?
>
> Oliver
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [Transaction] API, GenerickLock, FileResourceManager (was Re: Transaction API, GenericLock, FileResourceManager)

Oliver Zeigermann
On 6/27/05, Aaron Hamid <[hidden email]> wrote:
> I will use Thread.currentThread() for the "owner".  I'm not clear as to the utility of non-thread owners...what is the semantics of synchronization if the owners are not threads?  Or is the intention that owners ultimately must be associated with unique threads?

If something is actually blocked, it of course is the thread. But the
thread that does something on behalf of a therad owner may change,
e.g. when a transaction is suspended in one thread and resumed in
another. In something like JTA you will have to tell the TM about
this, in commons transaction you will not have to.

Oliver

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [Transaction] API, GenerickLock, FileResourceManager (was Re: Transaction API, GenericLock, FileResourceManager)

Aaron Hamid
Ah, I see!  So for instance the abstract notion of "owner" detached from thread can enable things like locks migrating across threads.  That's very interesting.

Thanks Oliver,

Aaron

Oliver Zeigermann wrote:

> On 6/27/05, Aaron Hamid <[hidden email]> wrote:
>
>>I will use Thread.currentThread() for the "owner".  I'm not clear as to the utility of non-thread owners...what is the semantics of synchronization if the owners are not threads?  Or is the intention that owners ultimately must be associated with unique threads?
>
>
> If something is actually blocked, it of course is the thread. But the
> thread that does something on behalf of a therad owner may change,
> e.g. when a transaction is suspended in one thread and resumed in
> another. In something like JTA you will have to tell the TM about
> this, in commons transaction you will not have to.
>
> Oliver
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [Transaction] API, GenerickLock, FileResourceManager (was Re: Transaction API, GenericLock, FileResourceManager)

Oliver Zeigermann
Exactly. But, as I said, there are other concepts (e.g. in JTA) that
work as well and sometimes even better.

Cheers

Oliver

On 6/27/05, Aaron Hamid <[hidden email]> wrote:

> Ah, I see!  So for instance the abstract notion of "owner" detached from thread can enable things like locks migrating across threads.  That's very interesting.
>
> Thanks Oliver,
>
> Aaron
>
> Oliver Zeigermann wrote:
> > On 6/27/05, Aaron Hamid <[hidden email]> wrote:
> >
> >>I will use Thread.currentThread() for the "owner".  I'm not clear as to the utility of non-thread owners...what is the semantics of synchronization if the owners are not threads?  Or is the intention that owners ultimately must be associated with unique threads?
> >
> >
> > If something is actually blocked, it of course is the thread. But the
> > thread that does something on behalf of a therad owner may change,
> > e.g. when a transaction is suspended in one thread and resumed in
> > another. In something like JTA you will have to tell the TM about
> > this, in commons transaction you will not have to.
> >
> > Oliver
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]