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

Proc-macros: can I call Server::new_with_config twice? #250

Open
ivmarkov opened this issue Jan 17, 2025 · 2 comments
Open

Proc-macros: can I call Server::new_with_config twice? #250

ivmarkov opened this issue Jan 17, 2025 · 2 comments

Comments

@ivmarkov
Copy link

ivmarkov commented Jan 17, 2025

(Please close if my analysis is incorrect - my code type-checks but I have not run it yet.)

It seems to me that calling Server::new_with_config a second time will panic, because the hidden AttributeTable uses a bunch of hidden StaticCells for its storage. Wouldn't calling it a second time end up with a panic, because you would be calling StaticCell::init twice?

In my use case, I do need the ability to call Server::new_with_config twice, because I need to support dynamic BLE stack tear-down / bring-up.
I can (and will) fix that with workarounds, like having an async mutex, that in turn contains Option<Server> and then I'll initialize the mutex on first use.

With that said, it is still a bit weird. As in the proc-macro bails with an error if you don't have the static_cell dependency in your crate (as was my case). Otherwise, I might not have even noticed that.
Also:

  • Isn't it better to have the necessary &mut [u8; <SUM_OF_ALL_GATT_ATTR_STORAGES>] storage be instead an argument to Server::new_with_config (ideally not &'static mut but &'some_lifetime mut)? This way you can trivially initialize the server multiple times, there is no dependency on static-cell in the proc-macro, and it is a bit more explicit to the user what is going on under the hood?
  • Why is this storage necessary in the first place? As in - the storage of the "level" attr right here should be the member variable itself? level: u8? Why a second storage in the form of a buffer? (Update: seems the level: u8 field is actually never materialized. It is just a hint how much storage to actually allocate in the attribute table, and then is also used for the T in Characteristic<T>.)
@lulf
Copy link
Member

lulf commented Jan 17, 2025

I think the simpler we can make the macros deal with the common cases, the better. If you need more advanced functionality, there is always the option of using the underlying API (though the only example of that right now is https://github.com/embassy-rs/trouble/blob/main/host/tests/gatt.rs#L46

@ivmarkov
Copy link
Author

How much more complex is the explicit variant I'm suggesting:

static RESOURCES: StaticCell<Server::Resources> = StaticCell::new();
...
void main() {
    let server = Server::new_with_config(..., RESOURCES::init(Resources::new()));

?

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

No branches or pull requests

2 participants