I have no stomach for further discussion/argument.

Thanks for the responses guys.

Dirk

On Tue, May 2, 2017 at 4:50 PM, Richard S. Hall <he...@ungoverned.org>
wrote:

> On 5/2/17 19:41 , Richard S. Hall wrote:
>
>> Resending to the mailing list...
>>
>> On 5/2/17 18:55 , Dirk Hogan wrote:
>>
>>> Hi Richard-
>>> I have a embedded jetty OSGi component that exposes the conglomeration of
>>> OSGi services to the outside world. Felix would need to set these service
>>> references in a thread-safe way. You appear to be suggesting that Felix
>>> can
>>> be only consumed by the Felix threads themselves, as only that would not
>>> bypass 'the hidden synchronization inside the framework' - whatever that
>>> is.
>>>
>>
>> I'm suggesting that if you pass objects to threads then you need to do so
>> in a thread safe way.
>>
>> Assume some something like:
>>
>> class FooThread {
>>     private MyService service;
>>     pubic void run() {
>>         while (true) {
>>             if (service != null) {
>>                 service.sayHello();
>>             }
>>         }
>>     }
>>     public void setService(MyService s) {
>>         service = s;
>>     }
>> }
>>
>> So lets assume that there is some thread spinning on run(). If in another
>> component you create a FooThread then get a service object from the service
>> registry and call myFooThread.setService() (where the MyService instance
>> contains your injected service), who is responsible for safely publishing
>> your service to your FooThread?
>>
>> Clearly, if you just call setService() you are not safely handing off the
>> service object to your thread (this is the equivalent of your shutdown flag
>> example). You are implying that it is the frameworks responsibility to
>> provide a barrier to FooThreads member service variable.
>>
>> Certainly, one solution to this is making your reference volatile, but
>> that it between you and FooThread, not between your service and the
>> framework.
>>
>
> Just some further elaboration and generalization, since the above may be
> confusing...
>
> The main point is you have some thread that you somehow have given access
> to an object and internally that object invokes some OSGi service. If you
> hand that object reference to your thread in a safe way, then there will be
> no problem.
>
> At the end of the day, the thread invoking this object had to be given the
> object reference by you, so you are responsible for giving it the reference
> using a barrier.
>
> -> richard
>
>
>
>> -> richard
>>
>>
>>> Let me try one more time: a while back, Felix mandated that DYNAMIC
>>> @References be volatile. Presumably that decision was made by someone who
>>> knows the JMM, and thus could provide a response to the question in my
>>> initial post:
>>>
>>> Perhaps an explanation as to why a DYNAMIC @Reference does need to be
>>> volatile would be helpful - e.g. why does component
>>> de-activation/re-activation provide memory visibility guarantees for
>>> STATIC
>>> references?
>>>
>>> I don't mean to be contentious, and there is nothing preventing me from
>>> declaring my @References volatile. I just was hoping that there was
>>> JMM-knowledge active in this forum which could provide an answer to my
>>> original question. I may well have my answer.
>>> Thanks
>>>
>>> Dirk
>>>
>>>
>>> On Tue, May 2, 2017 at 2:29 PM, Richard S. Hall <he...@ungoverned.org>
>>> wrote:
>>>
>>> Dirk,
>>>>
>>>> Allow I'm not well versed on the details of JMM. I think this boils down
>>>> to typical OSGi component code will be going through the hidden
>>>> barriers in
>>>> the the framework when they try to retrieve and access the service
>>>> objects.
>>>> You appear to be concocting a situation where you have threads from
>>>> outside
>>>> that you have given access to OSGi service components and bypassing the
>>>> hidden synchronization inside the framework. If you can create such a
>>>> scenario, then it is up to you to safely publish these objects when you
>>>> hand them off to this other thread. And the only way this is really
>>>> problematic is if your handoff is done in such a way that you bypass all
>>>> barriers to begin with.
>>>>
>>>> -> richard
>>>>
>>>>
>>>>
>>>> On 5/2/17 16:27 , Dirk Hogan wrote:
>>>>
>>>> Hi Neil-
>>>>> OK - now we are getting somewhere.
>>>>>
>>>>> You need to dig a bit deeper to see what establishes a happens-before
>>>>> relationship. For within a single thread, it is the Program Order: the
>>>>> underlying virtual machine cannot allow the visibility of memory
>>>>> effects
>>>>> which contradict the sequence of instructions defined in your .java
>>>>> file,
>>>>> even though these commands will be re-ordered by the compiler, and
>>>>> pipelined and executed concurrently by machine cores.
>>>>>
>>>>> Between threads, it is the Synchronization Order, which is NOT Program
>>>>> Order. Between threads, the memory effects of your .java file
>>>>> writes/reads
>>>>> do NOT have to be honored. So if you say 'But Felix writes the
>>>>> reference
>>>>> before publishing the service', and thus concluding that the reference
>>>>> will
>>>>> always be present in the service, you are correct, but ONLY from the
>>>>> perspective of the thread which wrote the reference and published the
>>>>> service. For ALL other threads, all bets are off, unless there is a
>>>>> Synchronization Action (volatile reference read/write, monitor
>>>>> lock/unlock
>>>>> on the same monitor) which dictates a Synchronization Order of the
>>>>> visibility of memory effects between DISTINCT threads.
>>>>>
>>>>> The definition of Synchronization Actions, how they combine to create a
>>>>> Synchronization Order, and how this, in turn, allows a happens-before
>>>>> relationship to be established, is a formal set of rules defined in the
>>>>> JMM. There is no ambiguity here. A read of section 17.4 will
>>>>> illuminate as
>>>>> much. It is very dense - that is why I turned to the other references I
>>>>> provided in the links above. They are not a quick/easy read, but are
>>>>> necessary to coherently reason about memory visibility across threads.
>>>>>
>>>>> Thanks
>>>>>
>>>>> Dirk
>>>>>
>>>>> On Tue, May 2, 2017 at 1:10 PM, Neil Bartlett <njbartl...@gmail.com>
>>>>> wrote:
>>>>>
>>>>> I think I get what Dirk is saying, and although I disagree with some of
>>>>>
>>>>>> his analysis there is arguably a gap in the DS specification that
>>>>>> makes
>>>>>> this unclear. I hope somebody can point at the vital sentence I have
>>>>>> missed, but here is my analysis:
>>>>>>
>>>>>> The JLS defines happens-before thus: "Two actions can be ordered by a
>>>>>> happens-before relationship. If one action happens-before another,
>>>>>> then
>>>>>> the
>>>>>> first is visible to and ordered before the second.” (
>>>>>> https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.
>>>>>> html#jls-17.4.5
>>>>>> <
>>>>>> https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.
>>>>>> html#jls-17.4.5
>>>>>>
>>>>>> ).
>>>>>>>
>>>>>>> Define two actions, A1 and A2. A1 is the setting of an @Reference
>>>>>> field
>>>>>> in
>>>>>> a component. A2 is reading the value of that field. It is Dirk’s
>>>>>> contention
>>>>>> that no provable happens-before relationship edge exists between A1
>>>>>> and
>>>>>> A2,
>>>>>> and therefore it’s possible for A2 to access the value of the
>>>>>> @Reference
>>>>>> field that obtained before A1. Let’s see.
>>>>>>
>>>>>> A1 is an action that is taken by SCR on an object that it creates (the
>>>>>> component instance). A2 can only occur in the following circumstances:
>>>>>>
>>>>>> 1. SCR itself reads the field.
>>>>>> SCR is in full control of its own code and I am assuming a correct SCR
>>>>>> implementation.
>>>>>>
>>>>>> 2. The activate method of the component uses the value of the field.
>>>>>> Section 112.3.8.1 of OSGi Compendium R6 states "there is a
>>>>>> happens-before
>>>>>> relationship between setting the field and activating the component
>>>>>> instance”. Also section 112.3.6.1 states “The bind method is called
>>>>>> and/or
>>>>>> the field is set before the component instance is activated”, which is
>>>>>> less
>>>>>> clear about the happens-before but I think the intent is there, and it
>>>>>> also
>>>>>> clarifies that this applies to bind methods as well as injected
>>>>>> fields.
>>>>>> Therefore action A1 happens-before A2 in this case.
>>>>>>
>>>>>> Note that the spec does not tell the implementation HOW to achieve
>>>>>> this
>>>>>> happens-before edge. As Dirk points out, if it is done with a
>>>>>> synchronized
>>>>>> block then it would have to be on the same monitor. For example, the
>>>>>> implementation can achieve this by synchronizing on the component
>>>>>> instance
>>>>>> itself when binding fields and calling the activate method.
>>>>>>
>>>>>> 3. The activate method starts a thread which uses the value of the
>>>>>> field
>>>>>> (I think this maps to Dirk’s HTTP-serving example).
>>>>>>   From point 2 above, we know that A1 happens-before the activate
>>>>>> method
>>>>>> is
>>>>>> invoked. JLS 17.4.5 states that “a call to start() on a thread
>>>>>> happens-before any actions in the started thread”. JLS also states
>>>>>> that
>>>>>> happens-before is transitive, i.e. if X happens-before Y and Y
>>>>>> happens-before Z then X happens-before Z.
>>>>>>
>>>>>> Therefore A1 happens-before A2 in this case.
>>>>>>
>>>>>> 4. Service method(s) on the component use the value of the field.
>>>>>> The analysis here diverges for immediate vs delayed components.
>>>>>>
>>>>>> For immediate components, Compendium section 112.5.3 states: "If an
>>>>>> immediate component configuration is satisfied and specifies a
>>>>>> service,
>>>>>> SCR
>>>>>> must register the component configuration as a service in the service
>>>>>> registry and then activate the component configuration”. This does NOT
>>>>>> state that the registration of the service must happen after the
>>>>>> binding
>>>>>> of
>>>>>> the reference fields. So it seems an implementation is free to hand
>>>>>> the
>>>>>> service object to a consumer before the static references are bound.
>>>>>> This
>>>>>> surprised me.
>>>>>>
>>>>>> For delayed components, Compendium section 112.5.4 states: "When the
>>>>>> service is requested … SCR must create and activate a [unique]
>>>>>> component
>>>>>> configuration”. It does NOT explicitly state that the static
>>>>>> references
>>>>>> must be bound before the service object is handed to the caller of
>>>>>> getService(). Again this surprised me.
>>>>>>
>>>>>>
>>>>>> In summary, it’s clear to me that the *intention* of the
>>>>>> specification is
>>>>>> for static references to be bound before the service becomes
>>>>>> accessible,
>>>>>> and that component writers should not have to declare those fields
>>>>>> volatile, but this intention is not adequately spelled out. The best
>>>>>> statement I could find is in section 112.3.6.1: "A component instance
>>>>>> never sees any of the dynamics of the static reference”, which is very
>>>>>> vague.
>>>>>>
>>>>>> Again, I may well have missed something or made an error in my
>>>>>> analysis.
>>>>>> I
>>>>>> look forward to be being corrected.
>>>>>>
>>>>>>
>>>>>> Neil
>>>>>>
>>>>>>
>>>>>> On 2 May 2017, at 19:56, David Jencks <david.a.jen...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> I don’t understand your example or I don’t understand how your
>>>>>>> example
>>>>>>>
>>>>>>> relates to an osgi or ds problem.
>>>>>>
>>>>>> I think you are proposing that the DS component is an http server and
>>>>>>>
>>>>>>> starts threads etc.  If so, it’s that components responsibility to
>>>>>> make
>>>>>> sure its’ internal operations are thread safe, and this has little to
>>>>>> do
>>>>>> with osgi or ds.
>>>>>>
>>>>>> If you are asking about osgi, for instance if the component exposes
>>>>>>>
>>>>>>> HttpServlet and is registered with the whiteboard http service and
>>>>>> receives
>>>>>> calls from it, then the whiteboard had to call getService to get the
>>>>>> DS
>>>>>> component instance. In this case I think that there are plenty of
>>>>>> synchronization barriers in the service registry and in e.g.
>>>>>> SingleComponentManager.getService to assure that the view a request
>>>>>> thread has of the component is the same as the view the activation
>>>>>> thread
>>>>>> had.
>>>>>>
>>>>>> I could be wrong about whether there are actually enough
>>>>>>> synchronization
>>>>>>>
>>>>>>> barriers.  Have you looked at the code to see?
>>>>>>
>>>>>> thanks
>>>>>>> david jencks
>>>>>>>
>>>>>>> On May 2, 2017, at 10:45 AM, Dirk Hogan <dirk.ho...@forgerock.com>
>>>>>>> wrote:
>>>>>>> Hi Raymond-
>>>>>>>
>>>>>>>> Assume Felix does it's thing: sets all @References, activates all
>>>>>>>> components, publishes all services. It has resolved all
>>>>>>>> dependencies,
>>>>>>>>
>>>>>>>> and
>>>>>>> set references accordingly.
>>>>>>>
>>>>>>>> Thus, in the example above, myOSGiComponent has its @Reference to
>>>>>>>> SomeOtherOSGiService resolved - Felix has set this reference. At the
>>>>>>>> conclusion of the activate method, myOSGiComponent has exposed some
>>>>>>>> functionality via http, even successfully dereferenced
>>>>>>>> myOSGiComponent,
>>>>>>>>
>>>>>>>> and
>>>>>>> now requests start to come it, serviced by the http-server's
>>>>>>> thread-pool.
>>>>>>> Part of servicing this request involves dereferencing (reading) the
>>>>>>>
>>>>>>>> @Reference myServiceReference, which, I agree has been set
>>>>>>>> (written) by
>>>>>>>>
>>>>>>>> a
>>>>>>> Felix thread.
>>>>>>>
>>>>>>>> The point of the Java Memory Model is that memory state, including
>>>>>>>> references, read and written across threads, do not have to have
>>>>>>>> determinate state, unless there is a Synchronization Action which
>>>>>>>>
>>>>>>>> ensures
>>>>>>> that the state written by thread A is visible to any other thread - a
>>>>>>>
>>>>>>>> volatile reference provides such a Synchronization Action. So code
>>>>>>>> in
>>>>>>>> myOSGiComponent activate method can successfully dereference the
>>>>>>>> SomeOtherOSGiService reference, because the same thread which set
>>>>>>>> the
>>>>>>>> reference is calling activate. But this does NOT mean that another
>>>>>>>>
>>>>>>>> thread,
>>>>>>> reading the SAME reference, will see a properly initialized
>>>>>>> reference.
>>>>>>>
>>>>>>>> Again, this should be self-evident, and the various rules of the JMM
>>>>>>>>
>>>>>>>> model
>>>>>>> are defined in section 17.4 of the Java Language Specification. If
>>>>>>> it is
>>>>>>>
>>>>>>>> not clear, then an understanding if the JMM is required. This
>>>>>>>>
>>>>>>>> understanding
>>>>>>> can be gained by reading the JLS, reading the links above, the
>>>>>>> chapter
>>>>>>>
>>>>>>>> in *Concurrency
>>>>>>>> in Practice* on the JMM,  or http://gee.cs.oswego.edu/dl/cp
>>>>>>>> j/jmm.html
>>>>>>>> provides a good intro.
>>>>>>>>
>>>>>>>> The bottom line: memory state, including references, shared among
>>>>>>>>
>>>>>>>> multiple
>>>>>>> threads can have indeterminate state when written/read, unless
>>>>>>> explicit
>>>>>>>
>>>>>>>> steps, defined in the JMM, are taken to ensure this visibility and
>>>>>>>> thus
>>>>>>>> coherent state. This is not an opinion.
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>>
>>>>>>>> Dirk
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, May 2, 2017 at 10:23 AM, Raymond Auge <
>>>>>>>> raymond.a...@liferay.com
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> On Tue, May 2, 2017 at 1:18 PM, Raymond Auge <
>>>>>>>> raymond.a...@liferay.com
>>>>>>>>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Tue, May 2, 2017 at 1:14 PM, Raymond Auge <
>>>>>>>>>>
>>>>>>>>>> raymond.a...@liferay.com>
>>>>>>>>>
>>>>>>>> wrote:
>>>>>>>
>>>>>>>> On Tue, May 2, 2017 at 11:46 AM, Dirk Hogan <
>>>>>>>>>> dirk.ho...@forgerock.com>
>>>>>>>>>>
>>>>>>>>> wrote:
>>>>>>>
>>>>>>>> But no similar guarantee applies when another thread hits the
>>>>>>>>>>>
>>>>>>>>>>>> component,
>>>>>>>>>>>>
>>>>>>>>>>>> I believe the discussion boils down to why you believe the
>>>>>>>>>>>> above is
>>>>>>>>>>>>
>>>>>>>>>>> possible?
>>>>>>>>>>>
>>>>>>>>>>> If SCR has not yet made the component available to other threads
>>>>>>>>>>>
>>>>>>>>>>> (which,
>>>>>>>>>>
>>>>>>>>> to my knowledge, it only does by registering it as a service to the
>>>>>>>
>>>>>>>> service
>>>>>>>>>> registry) how can _another_ thread access the component at all?
>>>>>>>>>>
>>>>>>>>>>> I don't even see a way for components within the same DS bundle
>>>>>>>>>>> to
>>>>>>>>>>> interact with each other other than via the service registry
>>>>>>>>>>> because
>>>>>>>>>>> @Reference only works through the registry.
>>>>>>>>>>>
>>>>>>>>>>> Correction, components could interact with each other via the
>>>>>>>>>>>
>>>>>>>>>> ComponentContext.. but I guess we'd have to know if that's part of
>>>>>>>>>>
>>>>>>>>>> your
>>>>>>>>>
>>>>>>>> use
>>>>>>>
>>>>>>>> case.
>>>>>>>>>>
>>>>>>>>>> Actually, no, it's not even possible via the ComponentContext. It
>>>>>>>>>>
>>>>>>>>> only
>>>>>>>>> allows access to Services.
>>>>>>>>>
>>>>>>>>> - Ray
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Please, can you explain in more detail what case might allow for
>>>>>>>>>> the
>>>>>>>>>>
>>>>>>>>>>> above? Because I believe the assumption is that it's not
>>>>>>>>>>> currently
>>>>>>>>>>> possible. Certainly there could be a bug and I'm certain everyone
>>>>>>>>>>>
>>>>>>>>>>> would
>>>>>>>>>>
>>>>>>>>> want to see that fixed.
>>>>>>>
>>>>>>>> --
>>>>>>>>>>> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>>>>>>>>>>> (@rotty3000)
>>>>>>>>>>> Senior Software Architect *Liferay, Inc.* <
>>>>>>>>>>> http://www.liferay.com>
>>>>>>>>>>> (@Liferay)
>>>>>>>>>>> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
>>>>>>>>>>> (@OSGiAlliance)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>>>>>>>>>> (@rotty3000)
>>>>>>>>>> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com
>>>>>>>>>> >
>>>>>>>>>> (@Liferay)
>>>>>>>>>> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
>>>>>>>>>> (@OSGiAlliance)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>>>>>>>>> (@rotty3000)
>>>>>>>>> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>>>>>>>>> (@Liferay)
>>>>>>>>> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
>>>>>>>>> (@OSGiAlliance)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>
>

Reply via email to