Skip to content

gh-125828 : Fix 'get_value' missing on [Bounded]Semaphore on multiprocessing MacOSX #125829

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

YvesDup
Copy link
Contributor

@YvesDup YvesDup commented Oct 22, 2024

This proposal is a workaround to fix absence of 'sem_getvalue' C function in the Semaphore MacOSX implementation.

Alls unit tests succeed except on test.test_concurrent_futures.test_init relative to the Resource Tracker manager.

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an alternative way to do it without a temporary class like this? (I don't have the answer but I feel it overcomplicates the code base)

# Specific MacOSX Semaphore
#

class _MacOSXSemaphore(SemLock):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to handle the SemLock class differently at the C level?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to handle the SemLock class differently at the C level?

As I mentioned in the problem, I'm waiting for feedback (from the Mac OS team ?) before going any further.

A C implementation is an option, even if it seems more complicated than Python.
That said, I'm available to go deep into the SemLock C code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, since the SemLock class is implemented in C, it's preferrable to first patch it there IMO. But let's CC some people I know they are on macOS: @ned-deily @ronaldoussoren @freakboy3742.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't profess any particular expertise in this area. However, given the underlying implementation is written in C, I agree that it makes some sense for the implementation of this workaround to also be in C (rather than have an underlying implementation that returns NotImplemented, wrapped by a layer that overrides that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than have an underlying implementation that returns NotImplemented, wrapped by a layer that overrides that.

The main idea is to listen to the acquire and release methods to update a shared counter, and to return the counter value when the get_value method is invoked.

I am going to open a new PR with a workaround written in C.

Comment on lines +140 to +141
util.debug(f"_MacOSXSemaphore:: creation of a {self.__class__.__name__}"\
f"with '{value = }'")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
util.debug(f"_MacOSXSemaphore:: creation of a {self.__class__.__name__}"\
f"with '{value = }'")
util.debug(f"_MacOSXSemaphore:: creation of a {self.__class__.__name__}"\
f"with {value=!r}")

def _acquire(self, *args, **kwargs) -> bool:
if self._semlock.acquire(*args, **kwargs):
with self._count:
util.debug(f"_MacOSXSemaphore: acquire {repr(self)}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
util.debug(f"_MacOSXSemaphore: acquire {repr(self)}")
util.debug(f"_MacOSXSemaphore: acquire {self!r}")

with self._count:
self._count.value += 1
self._semlock.release()
util.debug(f"_MacOSXSemaphore: release {repr(self)}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
util.debug(f"_MacOSXSemaphore: release {repr(self)}")
util.debug(f"_MacOSXSemaphore: release {self!r}")

@ZeroIntensity
Copy link
Member

This needs a NEWS entry :)

@ronaldoussoren
Copy link
Contributor

Is get_value part of the public API for these classes? The name suggests it is, but the method is not document in the reference docs and does not have a docsstring.

I haven't looked with enough detail at the code to be certain, and am not a multiprocessing expert, but I the code doesn't seem correct. In particular, how does the implementation handle blocking callers of acquire when the count is 0 but not when it is larger than 0?

@YvesDup
Copy link
Contributor Author

YvesDup commented Nov 4, 2024

is get_value part of the public API for these classes? The name suggests it is, but the method is not document in the reference docs and does not have a docsstring.

Yes, it is and I confirm this is not documented. This public method is rarely used to get a value of semaphore, except in unit tests. I should open an issue about this case.

In particular, how does the implementation handle blocking callers of acquire when the count is 0 but not when it is larger than 0?

As I explain it above, this class only listen to acquire and release to update shared counter and then call respectively acquire and releasemethods of _semlock class. When get_value is invoked, the class returns the counter value, and never calls the semlock._get_value method (which raises NotImplementedError).

In this way, the behaviour of semaphores is always done at a low level in the implementation of the semlockclass in the semaphore module (at C level).

@YvesDup YvesDup changed the title gh-125828 : Fix 'get_value' missing on [Bouded]Semaphore on multiprocessing MacOSX gh-125828 : Fix 'get_value' missing on [Bounded]Semaphore on multiprocessing MacOSX Nov 4, 2024
@YvesDup YvesDup closed this Apr 11, 2025
@YvesDup YvesDup deleted the semaphore-macosx-multiprocessing branch April 11, 2025 13:47
@YvesDup YvesDup restored the semaphore-macosx-multiprocessing branch April 11, 2025 13:47
@YvesDup YvesDup reopened this Apr 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants