09caf314f1
We decided to get rid of the C FFI for libs. It was becoming too intricate and complicated. It was becoming a technical burden and expanding into too much extra code. It's unfortunate, but we'll have to give up on getting out-of-tree hot-loadable libraries the easy way. It's possible to still do it with cross compilation or by keeping track of the libstdc++ version that the running harikoff binary was compiled against. Then we can ensure that our loadable lib code is linked against that same libstdc++ code and this should ensure ABI stability.
131 lines
4.0 KiB
C++
131 lines
4.0 KiB
C++
#ifndef __USER_SENSE_API_LIB_H__
|
|
#define __USER_SENSE_API_LIB_H__
|
|
|
|
#include <preprocessor.h>
|
|
#include <stdbool.h>
|
|
#include <user/senseDeviceSpec.h>
|
|
|
|
namespace hk {
|
|
namespace sense_api {
|
|
|
|
/* Exported by all sense API Libraries to tell Harikoff what API the lib uses
|
|
* to connect to providers; and also to state which implexor APIs it exports.
|
|
*/
|
|
typedef int (sal_mho_initializeRdyFn)(void);
|
|
typedef int (sal_mho_finalizeRdyFn)(void);
|
|
typedef int (sal_mho_attachDeviceAckFn)(const device::SenseDeviceSpec *const desc);
|
|
typedef int (sal_mho_detachDeviceAckFn)(const device::SenseDeviceSpec *const desc);
|
|
|
|
struct Sal_Mgmt_HkOps
|
|
{
|
|
// Lib calls this function to notify Harikoff that it's done initializing.
|
|
sal_mho_initializeRdyFn *initializeRdy;
|
|
// Lib calls this function to notify Harikoff that it's done finalizing.
|
|
sal_mho_finalizeRdyFn *finalizeRdy;
|
|
// Lib calls this to notify Harikoff that it's done attaching a device.
|
|
sal_mho_attachDeviceAckFn *attachDeviceAck;
|
|
// Lib calls this to notify Harikoff that it's done detaching a device.
|
|
sal_mho_detachDeviceAckFn *detachDeviceAck;
|
|
};
|
|
|
|
typedef int (sal_mlo_initializeIndFn)(void);
|
|
typedef int (sal_mlo_finalizeIndFn)(void);
|
|
typedef int (sal_mlo_attachDeviceReqFn)(const device::SenseDeviceSpec *const desc);
|
|
typedef int (sal_mlo_detachDeviceReqFn)(const device::SenseDeviceSpec *const desc);
|
|
|
|
struct Sal_Mgmt_LibOps
|
|
{
|
|
/* When Harikoff loads a sense API lib, it calls this function to initialize
|
|
* the lib. When this returns, the lib should be ready to attach devices.
|
|
*/
|
|
sal_mlo_initializeIndFn *initializeInd;
|
|
/* Harikoff calls this to finalize the lib and free its internal
|
|
* resources. When this returns, the lib should be ready to be unloaded.
|
|
*/
|
|
sal_mlo_finalizeIndFn *finalizeInd;
|
|
/* Harikoff calls this to attach a device to the lib. When it returns, the
|
|
* device should be attached and ready to be implexed.
|
|
*/
|
|
sal_mlo_attachDeviceReqFn *attachDeviceReq;
|
|
// When this returns, the device should be detached.
|
|
sal_mlo_detachDeviceReqFn *detachDeviceReq;
|
|
|
|
static bool sanityCheck(const Sal_Mgmt_LibOps &ops)
|
|
{
|
|
if (!ops.initializeInd || !ops.finalizeInd
|
|
|| !ops.attachDeviceReq || !ops.detachDeviceReq)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/* C++ version of the C struct above, which Harikoff uses to manage the
|
|
* lib and connect implexors to it.
|
|
*/
|
|
class SenseApiDesc
|
|
{
|
|
public:
|
|
class ExportedImplexorApiDesc
|
|
{
|
|
public:
|
|
ExportedImplexorApiDesc(const std::string name)
|
|
// The caller should sanity check before calling this constructor.
|
|
: name(name)
|
|
{}
|
|
|
|
static bool sanityCheck(const ExportedImplexorApiDesc &desc)
|
|
{
|
|
if (desc.name.empty()) { return false; }
|
|
return true;
|
|
}
|
|
|
|
public:
|
|
std::string name;
|
|
};
|
|
|
|
public:
|
|
SenseApiDesc() = default;
|
|
|
|
std::string stringify() const
|
|
{
|
|
std::string result = "Name: " + name + "\n";
|
|
result += "Exported Implexor APIs:\n";
|
|
for (const auto& api : exportedImplexorApis) {
|
|
result += " - " + api.name + "\n";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static bool sanityCheck(const SenseApiDesc &desc)
|
|
{
|
|
if (desc.name.empty() || desc.exportedImplexorApis.empty()) {
|
|
return false;
|
|
}
|
|
|
|
for (const auto& api : desc.exportedImplexorApis) {
|
|
if (!ExportedImplexorApiDesc::sanityCheck(api)) { return false; }
|
|
}
|
|
|
|
return Sal_Mgmt_LibOps::sanityCheck(desc.sal_mgmt_libOps);
|
|
}
|
|
|
|
std::string name;
|
|
// These are the implexors whose APIs this lib exports.
|
|
std::vector<ExportedImplexorApiDesc> exportedImplexorApis;
|
|
Sal_Mgmt_LibOps sal_mgmt_libOps;
|
|
};
|
|
|
|
#define HK_GET_SENSE_API_DESC_FN_NAME getSenseApiDesc
|
|
#define HK_GET_SENSE_API_DESC_FN_NAME_STR \
|
|
HK_QUOTE(HK_GET_SENSE_API_DESC_FN_NAME)
|
|
|
|
typedef const SenseApiDesc &(getSenseApiDescFn)(void);
|
|
|
|
} // namespace sense_api
|
|
} // namespace hk
|
|
|
|
#endif // __USER_SENSE_API_LIB_H__
|