-
Notifications
You must be signed in to change notification settings - Fork 60
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
Create a new UeventSender.sender object for every uevent call #255
Create a new UeventSender.sender object for every uevent call #255
Conversation
The UeventSender.sender class uses libudev under the covers. libudev's documentation (referenced below) states: > Only a single specific thread may operate on a given object during its > entire lifetime. It's safe to allocate multiple independent objects > and use each from a specific thread in parallel. However, it's not > safe to allocate such an object in one thread, and operate or free it > from any other, even if locking is used to ensure these threads don't > operate on it at the very same time. Therefore, if a test is multi-threaded and one thread calls to add devices the object might be created on that thread, then later another thread might remove the device and attempt to use the same object. For example, this can very easily happen in a ROS python-based environment where ROS spawns a new thread for each callback. Reference: https://www.freedesktop.org/software/systemd/man/latest/libudev.html
Hmm, shouldn't the caller either push all requests through the same thread or do sufficient synchronisations using locks? Otherwise we would begin to define umockdev to be threadsafe at least for some operations. I am just wondering whether or not that is desirable. |
@benzea: Pushing all requests through the same thread would be difficult in ROS (specifically rospy which is what I'm using this in) since for every callback ROS spins up a new thread to run the callback. Therefore, I would have to have my code place the event on a queue and then have a thread setup only to make calls to umockdev. Locking would not solve this as that only prevents umockdev from being accessed simultaneously by two separate threads not two separate threads accessing the umockdev structures within a mutex. (I already have a mutex preventing simultaneous access to umockdev and don't mind that restriction at all.) I'm not asking umockdev to be multi-thread safe in general, but in this case, in my opinion, it is quite a burden to place on the client (and a surprising restriction) to require that all calls to umockdev be done from a single thread. Also, such a restriction, if intentional, would need to be well-documented. |
Hmm 🤔 My initial reaction was "let's make an UEventSender instance hash table per thread id". However, So I'm personally fine with this if it helps @bobhenz-jabil -- there is no written guarantee for umockdev to be threadsafe in all cases, and indeed I never bothered with this (such as avoiding globals). @benzea do you strongly object to this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sorry for late answer -- I'm back from vacation now)
Nah, fine with me. I just mostly feared it would set a precedence for thread safety in general. |
Thank you! |
The UeventSender.sender class uses libudev under the covers. libudev's documentation (referenced below) states:
Therefore, if a test is multi-threaded and one thread calls to add mock devices the object might be created on that thread, then later another thread might remove the mock device and attempt to use the same libudev object.
For example, this can very easily happen in a ROS python-based environment where ROS spawns a new thread for each callback.
While I don't know what the failure might look like (as I was seeing a different crash at the time I stumbled upon this), the libudev documentation is rather concerning given how this was being used.
Reference: https://www.freedesktop.org/software/systemd/man/latest/libudev.html