1

I have an application that imitates state of a vehicle and uses various plugins to transmit data. Each plugin is loaded dynamically and provides protocol-specific implementation for an interface to send the data. By specification each plugin may be operating concurrently and a sending method may be asynchronous.
I would like to be able to share asio::io_context or asio::thread_pool to utilize those resources allocated by the application (core). Each plugin would use asio::strand if needed. I really wouldn't want plugins to spawn new threads.

To provide compiler independence the API for a plugin is in C, hence I can't pass asio entities just like that.

Is it possible though to expose a context or a thread pool to a dynamically loaded dll which may be compiled with another toolchain?
Maybe via some kind of native handles?
Maybe I could wrap a custom executor? I didn't find any constructors in the reference which would use native handles, etc.

Sergey Kolesnik
  • 3,009
  • 1
  • 8
  • 28
  • Since you're obviously using a recent enough version of Asio, at least don't share `io_context`/`thread_pool` references. These are execution contexts, and the preferred way to share "knowledge" about them is using executors. Besides, I'm trying hard to think of reasons to share execution contexts. Unless you have maybe thousands of different plugins, there should not be a lot of overhead of having the separate service registries. So, maybe just sharing executors and having separate execution context /if necessary/ might be a sane starting point? – sehe Jun 01 '21 at 17:12
  • Fir the rest you basically have the usual ABI/ODR constraints which would make it tricky to get stable plugins unless all plugins originate from the same build system. – sehe Jun 01 '21 at 17:13
  • Reading your last para you seem to be asking whether executors can act as ABI firewall. I think the answer is no: executors are lightweight but not trivial. In fact many will just amount to a virtual dispatch table optionally adding type erasure. (Type erasure is fine across DLL boundaries, but only for transparent traversal and use back in the original module?) – sehe Jun 01 '21 at 17:17
  • @sehe I am using C-wrapper struct with pointers to expose C++ classes. I don't pass ownership over resources. I have an idea to wrap an executor to a C struct with pointers and then "unwrap" it utilizing `executor` traits. This approach worked fine with `completions`. – Sergey Kolesnik Jun 01 '21 at 18:32
  • The question is which side of the library-boundary does the unwrapping and to what types. That's precisely the caveat I meant in my last (parenthesized) sentence. Completions are different, in that they are usually C-compatible signatures (though boost::system::system_error could invite issues back) – sehe Jun 01 '21 at 18:53
  • @sehe the application core provides wrapped C structs with pointers. Plugin imports them and unwraps to a C++ class that has `executor` traits. I didn't check it yet though. I am not very sure it would work, however, since `asio` specific types are likely to be involved. – Sergey Kolesnik Jun 01 '21 at 19:03

0 Answers0