Hi all,

while looking into
https://issues.apache.org/bugzilla/show_bug.cgi?id=45194 I realized
that we are currently pretty inconsistent with our usage of locking in
Project.

Right now we have:

* locking on the Project instance for the logging subsystem (add or
  remove a BuildListener and the actual logging)

* locking on the PropertyHelper instance on all public PropertyHelper
  methods

* locking on the Project instance when associating a task with the
  current thread - but not when reading it

* locking of the references table when setting a reference, but not
  when reading it

The first two cause the race condition noted in the bug report since
the methods in PropertyHelper may log stuff while another thread is
active logging something and its currently executing BuildListener
tries to read property.

There are two places where we potentially call external (non-Ant) code
inside of a synchronized section: while logging (a BuildListener) and
while accessing properties (a PropertySetter or PropertyEvaluator).
Either should be avoided, but I'm not sure we can.

We use locking for the log system for two reasons: locking the
collection of listeners and setting a flag that allows us to detect
recursive invocations of the logging system in order to avoid infinite
loops (a BuildListener writing to System.out/err).

I suggest the following changes:

* add locking to getThreadTask, but don't use the project instance but
  rather something like the threadTasks table (and use that in
  registerTreadTask, of course).

* remove the locking of references completely.  Given we hand out full
  control via Project.getReferences to whoever is there, locking the
  write access to make the "do I need to print a warning? Add the
  reference" operation atomic seems pretty useless to me.

* lock the listener collection in the add/remove listener methods,
  in fireMessageLogged lock the listeners, clone them, give up the
  lock, work on the clone

* turn the loggingMessage flag into a ThreadLocal, don't lock for it
  at all.

  The last two changes allow BuildListeners to be executed without
  holding any locks - this should avoid the deadlock in issue 45194.

* I'm not completely sure what the reasons for locking in
  PropertyHelper are and whether:

  * lock the delegates collections in add and clone it in all the
    other methods

  * invoke the delegate without any locks

  * lock on the property helper instance after all delegates have been
    invoked

  would meet all the needs.  Matt?

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to