You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by "Peter Jones (JIRA)" <ji...@apache.org> on 2007/07/28 00:35:52 UTC
[jira] Created: (RIVER-145) JoinManager synchronization on
serviceItem should be reviewed, doc'd and fixed where appropriate
JoinManager synchronization on serviceItem should be reviewed, doc'd and fixed where appropriate
------------------------------------------------------------------------------------------------
Key: RIVER-145
URL: https://issues.apache.org/jira/browse/RIVER-145
Project: River
Issue Type: Bug
Components: net_jini_lookup
Affects Versions: jtsk_2.1
Reporter: Peter Jones
Priority: Minor
Bugtraq ID [6219020|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219020]
The object {{JoinManager.serviceItem}} and its fields are accessed (read
and written) in a number of threads/tasks in {{JoinManager}}. In most cases,
that access is controlled through synchronization on either {{serviceItem}}
or the {{JoinManager.joinSet}} object. But there are a few places where the
access to {{serviceItem}} fields is not synchronized at all.
The synchronization strategy and implementation for {{serviceItem}} should
be reviewed and corrected where necessary.
See the comments for a 'map' of {{serviceItem}} synchronization, and a
description of the synchronization strategy regarding {{serviceItem}}.
h4. ( Comments note: }
{noformat}
JoinManager {
ServiceItem serviceItem
- serviceID
- service
- attributesSets
}
{noformat}
-- Synchronization Strategy for {{serviceItem}} --
{{serviceItem}} is instantiated in {{createJoinManager()}} when the {{JoinManager}} is
created and initialized. After instantiation, only the fields of {{serviceItem}}
are accessed by the various threads. Access to those fields is controlled by
synchronizing on either {{serviceItem}} itself, on {{joinSet}}, or on both.
- Access to the {{serviceID}} field is controlled by synchronizing on
{{serviceItem}} itself.
- Access to the service and {{attributeSets}} fields is controlled by
synchronizing on {{joinSet}}.
The reason that {{joinSet}} is not used to control access to all the fields of
{{serviceItem}} is because deadlock can occur if the sync on {{serviceItem}} in
{{ProxyRegTask.runAfter()}} is changed to a sync on {{joinSet}}. This deadlock
can occur because the {{TaskManager}} actually executes the {{runAfter()}} method
inside of a sync block on the {{TaskManager}} itself. Thus,
{noformat}
A. LUS-0 discovered
DiscMgrListener.discovered() -- LUS-0
sync(joinSet)
addTask(RegisterTask-0)
sync(taskList)
taskList.add(RegisterTask-0)
sync(taskMgr)
taskMgr.add(ProxyRegTask-0) ---------------------|
}//end sync |
}//end sync |
}//end sync |
|
B. TaskManager.run(ProxyRegTask-0)
|-- sync(taskMgr) -- (lock-1)
C. LUS-1 discovered | ProxyRegTask-0.runAfter()
| .
DiscMgrListener.discovered() -- LUS-1 | .
sync(joinSet) -- (lock-2) ----------| | .
addTask(RegisterTask-1) |-------- sync(joinSet) (wait on lock-2)
sync(taskList) |
taskList.add(RegisterTask-1) |
sync(taskMgr) (wait on lock-1) --| *** DEADLOCK ***
{noformat}
Thus, to avoid the above deadlock, {{runAfter()}} and {{ProxyReg.register()}} both
synchronize on {{serviceItem}} before accessing the {{serviceID}} field of
{{serviceItem}}. For access to the other fields of {{serviceItem}}, synchronizing
on {{joinSet}} seems to be sufficient; although, as the map below shows,
there are places where no synchronization occurs, but should be
considered.
{noformat}
-- Synchronization Map --
serviceItem field access location access type synchronization
----------------- ----------------------- ----------- -----------------
a.) serviceID ProxyRegTask.runAfter() read sync(serviceItem)
ProxyReg.register() read write sync(serviceItem)
b.) service ProxyReg.register() read write sync(joinSet)
& sync(serviceItem)
DiscMgrListener.discovered() read sync(joinSet)
replaceRegistrationDo() write sync(joinSet)
*** createJoinManager() write NO SYNC
(when serviceItem instantiated)
c.) attributeSets addAttributes() write sync(joinSet)
setAttributes() write sync(joinSet)
modifyAttributes() write sync(joinSet)
replaceRegistrationDo() write sync(joinSet)
*** createJoinManager() write NO SYNC
(when serviceItem instantiated)
{noformat}
h4. ( Suggested Fix note: )
Currently, the only place in {{JoinManager}} where access to the fields of
{{serviceItem}} are not synchronized is in {{createJoinManager()}}. In that
method, the {{serviceItem}} is created (and its fields are written to) when
the {{JoinManager}} itself is constructed and initialized. Because this occurs
during construction/initialization, before any tasks or threads that access
{{serviceItem}} have been started, it may not be necessary to synchronize
access to that new {{serviceItem}} in {{createJoinManager}}.
Thus, there may not currently be any sort of defect associated with
synchronization on {{serviceItem}} in {{JoinManager}}. This bug report can
then be viewed as a location to document any future defects or changes
related to that synchronization.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.