Feature request for lcb_create_io_ops
We use the lcb_create_io_ops() function for integrating Couchbase with our own event loop. This function has two modes of operation - if I understand correctly:
1. Use an event loop out of a set of predefined event loops (libev, libevent, etc)
2. Specify a shared .so library file and the name of a function that takes care of the event loop.
For us, the first option does not work. Although we do use libev (which is supported), we use it with static linking as we do not want to rely on libev being available on sometimes outdated target machines. When we tell lcb_create_io_ops() to use libev, the couchbase libev plugin still tries to open the libev.so library file - which is exactly what we do not want.
We have thus opted for the second option, but this is not ideal either. We have implemented the custom event loop in our main application, and not in a .so file. The most simple solution for us would have been to just tell lcb_create_io_ops() the address of our function - instead of the name of a .so file (which we don't have) and the name of this function.
The solution that we now have taken is this: We specify NULL as the name of the .so file, so that couchbase will look in the main application symbol table for the function, and we have added many extra options to the compiler so that the function can actually been found:
lcb_error_t setup_couchbase_io(int version, lcb_io_opt_t *io, void *arg)
{
...
}
lcb_io_opt_t ioops;
struct lcb_create_io_ops_st ciops;
ciops.version = 1;
ciops.v.v1.sofile = NULL;
ciops.v.v1.symbol = "setup_couchbase_io";
ciops.v.v1.cookie = our_cookie;
lcb_create_io_ops(&ioops, &ciops)
And we had to add the following options to the gcc compiler, because the dlsym() method that couchbase uses does not by default find symbols that are loaded from the static libraries (.a files) that we use.
-Wl,-u,setup_couchbase_io -rdynamic
My suggestion would be to make it simpler:
lcb_error_t setup_couchbase_io(int version, lcb_io_opt_t *io, void *arg)
{
...
}
lcb_io_opt_t ioops;
struct lcb_create_io_ops_st ciops;
ciops.version = 2;
ciops.v.v2.function = setup_couchbase_io;
ciops.v.v2.cookie = our_cookie;
lcb_create_io_ops(&ioops, &ciops)This is faster, simpler, and does not require all those funny compiler options.
Thanks.
The reason why you need to add the -u to the linker is because you don't reference the function anywhere else in your code, and linkers won't extract symbols from archives unless they are undefined. If you just reference the function in your code you don't have to add it as undefined.
That being said: you don't have to call the lcb_create_io_ops() function just to have it call your function. The purpose of lcb_create_io_ops is to load libraries and do the magic to look up the symbols in the code. If people don't care about which backend they use, they could just pass on "DEFAULT" and it would pick one that is available
on the platform etc. Since you are doing static linking and your own customized io event you can just call your own function to create your io ops and pass that on to lcb_create.
cheers,
Trond
Hello Emiel,
I am pushing that to the C SDK team to see what they think about your proposal.
Regards
Tug
@tgrall