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

chore(cbindings): avoid using global var in libwaku.nim #2118

Merged
merged 7 commits into from
Oct 23, 2023

Conversation

Ivansete-status
Copy link
Collaborator

Description

Applying Jacek's recommendation which is to prevent using global variable. That way we provide more flexibility to the library users. For example, we could start multiple wakunode instances within the same app.

Original recommendation: #1865 (comment)

Changes

  • Remove global variable from libwaku.nim.
  • Extract the ctx variable to outside the library so that the Context can be passed to any other libwaku function.
  • Addition of int callerRet parameter to WakuCallback. This parameter allows the caller to indicate whether the callback call was a successful or erroneous one.
  • Adding void* userData parameter to every library function. This is useful to attach closure reference in Rust.
  • Adapting the C code example.

Issue

#1878

* Avoid using a global variable to store the Context object.

* Better signature for the callback. Two new parameters added:
  one aimed to allow passing the caller result code; and the other
  param is to pass an optional userData pointer that might need
  to be linked locally with the Context object. This is needed
  in Rust for example, to make the passed closures to live as
  long as the Context.
@github-actions
Copy link

github-actions bot commented Oct 9, 2023

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:2118

Built from 7a34a04

@Ivansete-status Ivansete-status marked this pull request as ready for review October 9, 2023 11:27
@Ivansete-status Ivansete-status self-assigned this Oct 9, 2023
Copy link
Contributor

@NagyZoltanPeter NagyZoltanPeter left a comment

Choose a reason for hiding this comment

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

Pretty cool step ahead! Thank you!

I think it is quite well polished overall.
I just have some notice for the future to think of but handle it as a personal flavour.

I think in general library internal memory shall not be exposed to client. I personally more like to name it as handle (e.g. ContextHandle that can be checked if that maps to a real object allocated in the library, rather believe caller gives us the right pointer back). Main reason that any kind of mess in the usage will point to library failure, like crash or something.

Similar but even harder to solve in C the thingy with returning strings through callback.
We should trust client code that our message pointer will not outlive the callback call or GC (does GC enabled in libwaku?) can free or reuse it causing weird working in the user code.

In the example program I would encourage use strncpy not to trust ever 0 ending.
Also malloc call is better "malloc((len+1)*sizeof(char))" in case sometime ever it turns to wchar_t. But this one is really for habits, not a bug in this particular case.

@Ivansete-status
Copy link
Collaborator Author

Thanks for the comment and for checking it! 🔥

I reply to a couple of points:

Similar but even harder to solve in C the thingy with returning strings through callback. We should trust client code that our message pointer will not outlive the callback call or GC (does GC enabled in libwaku?) can free or reuse it causing weird working in the user code.

Good point! I'll revisit all points where we return information through the callback approach to make sure the strings are properly allocated, live during the callback call, and are freed afterwards.

In the example program I would encourage use strncpy not to trust ever 0 ending. Also malloc call is better "malloc((len+1)*sizeof(char))" in case sometime ever it turns to wchar_t. But this one is really for habits, not a bug in this particular case.

Very good point indeed! Something to enhance but not urgent.


// Creates a new instance of the waku node.
// Sets up the waku node from the given configuration.
int waku_new(const char* configJson, WakuCallBack onErrCb);
int waku_new(void* ctx,
Copy link
Contributor

Choose a reason for hiding this comment

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

for the context, a useful trick is to define an opaque type for it (typedef struct WakuContext WakuContext;) and pass around WakuContext* instead of void* - this documents intent and gives some rudimentary type safety (even if it's limited in C).

@Ivansete-status Ivansete-status merged commit 1e8f577 into master Oct 23, 2023
9 of 10 checks passed
@Ivansete-status Ivansete-status deleted the cbindings-avoid-global-var branch October 23, 2023 06:37
omahs pushed a commit to omahs/nwaku that referenced this pull request Nov 21, 2023
* libwaku: Avoid global variable and changing callback signature

* Better signature for the callback. Two new parameters have been added:
  one aimed to allow passing the caller result code; the other
  param is to pass an optional userData pointer that might need
  to be linked locally with the Context object. For example, this is needed
  in Rust to make the passed closures live as
  long as the Context.

* waku_example.c: adaptation to the latest changes

* libwaku.h: removing 'waku_set_user_data' function

* libwaku.nim: renaming parameter in WakuCallBack (isOk -> callerRet)
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.

5 participants