cancel
Showing results for 
Search instead for 
Did you mean: 
SOLVED

Datalayer SDK calling assumptions for safe Rust bindings

Datalayer SDK calling assumptions for safe Rust bindings

kulst
Occasional Visitor

Hello everyone,

I am currently working on using the ctrlX Datalayer from the Rust programming language.
As soon as I have the basic functionalities working, I want to provide an open source library similar to the golang bindings already available on Github.

To achieve this I am using the Datalayer C interface. I already have working Rust bindings to the C API and was able to successfully link my library prototype to libcomm_datalayer. So calling the C API from Rust works.

For those who do not know what Rust is:
Rust is a systems programming language as C and C++ are. One of the main benefits of Rust compared to these two is, it provides memory-safety and thread-safety. And it does this without a garbage collector. Instead it analyzes the code at compile time and uses features like an ownership model. As long as you do not use the unsafe keyword in Rust a compiled program is mostly safe regarding these points.

Unfortunately calling functions from another C API is inherently unsafe in Rust as it can not provide any guarantees for the C API. So one common pattern in Rust is to wrap the unsafe API calls into a safe Rust API.
I want to do this for the Datalayer SDK C API. For example: My prototype is already able to make sure that clients and providers can not outlive their datalayer system (guaranteed at compile time).

To achieve this goal it would be very helpful for me to get a better understanding what the assumptions of the API are. One example for this is that the system must be started to get a valid pointer from DLR_systemFactory(..).

Things that are especially interesting:

  • Multithreading behaviour (for example: does the system/client/provider/node etc. have to be deleted in the same thread as where it was created?)
  • How do the async callbacks work? Where are they called from?
  • Maybe other assumptions?

I would be very glad if you could help me.

Cheers kulst

1 REPLY 1

tiramisu
Member

  • Multithreading behaviour (for example: does the system/client/provider/node etc. have to be deleted in the same thread as where it was created?)

The api is threadsafe. So you can call any interface function from any thread. For example: If you use a client you can make requests from any thread.

  • How do the asynch callbacks work? Where are they called from?

Each client/provider you create has a own thread. If you do a request, this request is forwarded to the client thread and processed there. If there is an answer, the callback will be called in context of this client thread (asynch case). The syncronous method call simply waits for this callback and returns.

Same for a provider. All onRead()/on...() methods are called from the provider thread. So there is a linearization of all requests. It's also allowed to forward the callback if your on...() method to a worker thread and call it there. So its possible to anser it in an asynchronous way. This you should use if you don't want to block your provider if the answer of the request will take a long time. The provider detects that the callback was not called and keeps the request alive this a configurable timeout.

Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist