Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrency issues #4

Open
pbvahlst opened this issue Sep 21, 2013 · 4 comments
Open

Concurrency issues #4

pbvahlst opened this issue Sep 21, 2013 · 4 comments

Comments

@pbvahlst
Copy link

Hi there, nice little API :-)

It has some concurrency issues though which needs attention, I will be happy to give some pointers if the project is still active. E.g.

OSCPacketDispatcher:
You need to use a ConcurrentHashMap for this to be thread safe, if you where to add a listener after OSCPortIn has started receiving messages there could be visibility issues of the newly added listener and ConcurrentModificationExceptions could occur

OSCMessage:
is not Immutable and therefore not thread safe. This can cause issues with visibility when crossing thread boundaries

OSCPortIn:
The listening flag will be accessed by multiple threads and is not currently thread safe. Should be changed to volatile or accessed In thread safe manner. If not this could cause visibility issues and in worst case it will never stop running because it want see the state change of the listening flag.

.... More issues....

@ciyer
Copy link
Collaborator

ciyer commented Sep 25, 2013

Hi,

Thanks for taking such a close look at the code.

2013/9/21 Peter Vahlstrup [email protected]

OSCPacketDispatcher:

You need to use a ConcurrentHashMap for this to be thread safe, if you
where to add a listener after OSCPortIn has started receiving messages
there could be visibility issues of the newly added listener and
ConcurrentModificationExceptions could occur

The OSCPortIn is not designed to allow modifying the address space while
running.

Switching to a ConcurrentHashMap would prevent the possibility of seeing an
incoherent state of the underlying map in this situation, but it would not
make the class thread safe. The thread safety would depend on how it was
used (e.g., think about the case that a client wants to add a new listener
for an address if there was none already registered -- additional
synchronization would be required).

We should update the class documentation to clarify the intended use of the
class.

OSCMessage:
is not Immutable and therefore not thread safe. This can cause issues with
visibility when crossing thread boundaries

OSCMessage is not designed to be mutated in multiple threads. This is
unfortunately not reflected in the design -- if I were to design the API
again, I would use the builder pattern to construct message objects and
have all fields of the message objects final...

We should document make the intended use of the class clear in the class
documentation.

OSCPortIn:
The listening flag will be accessed by multiple threads and is not
currently thread safe. Should be changed to volatile or accessed In thread
safe manner. If not this could cause visibility issues and in worst case it
will never stop running because it want see the state change of the
listening flag.

This is indeed a bug. Nice catch!

Sekhar

C. Ramakrishnan [email protected]

@pbvahlst
Copy link
Author

Happy to help :)

Switching to a ConcurrentHashMap would prevent the possibility of seeing an incoherent state of the underlying map in this situation, but it would not make the class thread safe. The thread safety would depend on how it was used (e.g., think about the case that a client wants to add a new listener for an address if there was none already registered -- additional synchronization would be required).

Agreed, sorry for vague formulation

OSCMessage is not designed to be mutated in multiple threads. This is unfortunately not reflected in the design -- if I were to design the API again, I would use the builder pattern to construct message objects and have all fields of the message objects final...

Even though it shouldn't be mutated in another thread there will (could) still be visibility issues if the setters and getters are not synchronized or the fields are not final. That is if the object crossed thread boundaries (on multi-core processors). the Java Memory Model describes this: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5-110

danieldickison added a commit to danieldickison/JavaOSC that referenced this issue Mar 25, 2018
This should make this thread-safe as long as startListening() and stopListening() are only called from a single thread. Takes care of part of issue hoijui#4
@Burtan
Copy link
Contributor

Burtan commented Jan 9, 2021

I think there is one more threading problem. When you send data one OSCSerializer is built per sending operation, as it is not thread safe, but they all share the buffer from the OSCPortOut.

@DiMoSe
Copy link

DiMoSe commented Aug 2, 2021

I'm consistently getting an error when receiving values quickly. I figure it's not hard to avoid, I really don't need to receive the instructions that quickly but thought it related to this thread. If you need any more info I can provide to help fix this let me know, it's quite easy to reproduce.

Exception in thread "Thread-1" java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
	at com.illposed.osc.OSCPacketDispatcher.dispatchMessageNow(OSCPacketDispatcher.java:401)
	at com.illposed.osc.OSCPacketDispatcher.dispatchPacket(OSCPacketDispatcher.java:287)
	at com.illposed.osc.OSCPacketDispatcher.handlePacket(OSCPacketDispatcher.java:300)
	at com.illposed.osc.transport.OSCPortIn.run(OSCPortIn.java:199)
	at java.base/java.lang.Thread.run(Thread.java:831)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants