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

Conversion from/to raw handle #57

Merged
merged 6 commits into from
Mar 28, 2023

Conversation

agerasev
Copy link
Contributor

  • For Semaphore, Task and Timer: added method to get raw handle (raw_handle).
  • For Mutex:
    • Added methods to convert from/to inner parts and to get mutable access to them.
    • Added from_raw_handle and raw_handle to non-owning mutexes (MutexInnerImpl).

@@ -126,6 +123,9 @@ where
fn create() -> Result<Self, FreeRtosError>;
fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError>;
fn give(&self);

unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a risk that the wrong type of handle is passed in here and later treated incorrectly? E.g. if MutexRecursive::from_raw_handle() is called with a handle made via xSemaphoreCreateBinary(), what happens when that MutexRecursive instance is used to give/take? The docs for xSemaphoreTakeRecursive() say this, which sounds like it would be a problem:
The mutex must have previously been created using a call to xSemaphoreCreateRecursiveMutex();
I also see the CreateRecursiveMutex docs say:
xSemaphoreTake() and xSemaphoreGive() must not be used.

It's not necessarily a deal breaker, but it would be nice to avoid such errors and confusion.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Links to docs I mentioned:
https://www.freertos.org/xSemaphoreTakeRecursive.html
https://www.freertos.org/xSemaphoreCreateRecursiveMutex.html

Also occurs to me that this could cause issues if the user leaks the handle with raw_handle() and then drops the owning struct, leaving the handle invalid behind.

What are you envisioning is the use for the user accessing the raw handle like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a risk that the wrong type of handle is passed in here and later treated incorrectly?

Yes, such risk exists as well as risk of passing a null or dangling pointer. This method is unsafe and that usually means that it's up to user to ensure that the handle passed is valid and of correct type.
I didn't find a way to check the mutex type in FreeRTOS API. It seems, that the only thing we can do here is to write a doc comment to draw the user's attention to possible mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also occurs to me that this could cause issues if the user leaks the handle with raw_handle() and then drops the owning struct, leaving the handle invalid behind.

Yes, such issue is also possible. But the raw handle is just a pointer and it's safe in Rust to have dangling pointers. And if you want to use that raw handle you need to call from_raw_handle which is unsafe that means you have to make sure that the raw handle is valid.

Copy link
Contributor Author

@agerasev agerasev Mar 22, 2023

Choose a reason for hiding this comment

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

What are you envisioning is the use for the user accessing the raw handle like this?

In my case I just needed to get a task identifier which is unique among existing tasks. And for completeness I've added the raw_handle method to all types that already have from_raw_handle and also added raw handle conversion for mutexes.

It's common practice for safe Rust wrappers of foreign API to provide an access to underlying unsafe entities (for example, raw fd traits in Rust stdlib). This can be useful when you want to interoperate with foreign code or use some API functions that aren't yet supported by the wrapper.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fair enough. I see you already added a comment here but any other new unsafe functions should have comments (this always seemed like a good guide to me for reference)

@schteve
Copy link
Collaborator

schteve commented Mar 28, 2023

Looks good to me. Thanks for going above and beyond on this one!

@schteve schteve merged commit bbacc44 into lobaro:master Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants