Async: add sh_ptr<ContinuationChainLink> to Callback<>
This change enables us to finally implement the tracing of continuations backward from the point of acquisition for deadlock debugging.
This commit is contained in:
@@ -9,8 +9,10 @@
|
||||
#include <opts.h>
|
||||
#include <user/senseApiDesc.h>
|
||||
#include <user/deviceAttachmentSpec.h>
|
||||
#include <callback.h>
|
||||
#include <livoxProto1/livoxProto1.h>
|
||||
#include <livoxProto1/device.h>
|
||||
#include <asynchronousContinuation.h>
|
||||
|
||||
|
||||
namespace smo {
|
||||
@@ -50,6 +52,105 @@ static LivoxProto1DllState livoxProto1;
|
||||
// Attached Livox devices
|
||||
static std::vector<std::shared_ptr<livoxProto1::Device>> g_attachedDevices;
|
||||
|
||||
// Continuation classes for async operations
|
||||
class AttachDeviceReq
|
||||
: public smo::NonPostedAsynchronousContinuation<sal_mlo_attachDeviceReqCbFn>
|
||||
{
|
||||
public:
|
||||
AttachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
|
||||
smo::Callback<sal_mlo_attachDeviceReqCbFn> cb)
|
||||
: smo::NonPostedAsynchronousContinuation<sal_mlo_attachDeviceReqCbFn>(
|
||||
std::move(cb)),
|
||||
spec(spec)
|
||||
{}
|
||||
|
||||
public:
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec> spec;
|
||||
|
||||
public:
|
||||
void attachDeviceReq1(
|
||||
std::shared_ptr<AttachDeviceReq> context,
|
||||
bool success, std::shared_ptr<livoxProto1::Device> dev)
|
||||
{
|
||||
if (!dev)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to create Livox device: "
|
||||
<< context->spec->deviceSelector << std::endl;
|
||||
context->callOriginalCb(false, context->spec);
|
||||
return;
|
||||
}
|
||||
|
||||
g_attachedDevices.push_back(dev);
|
||||
if (1 || OptionParser::getOptions().verbose)
|
||||
{
|
||||
std::cout << __func__ << ": Successfully attached Livox "
|
||||
"device: " << context->spec->deviceSelector << " (ID: "
|
||||
<< context->spec->deviceIdentifier << ")\n";
|
||||
}
|
||||
|
||||
context->callOriginalCb(success, context->spec);
|
||||
}
|
||||
};
|
||||
|
||||
class DetachDeviceReq
|
||||
: public smo::NonPostedAsynchronousContinuation<sal_mlo_detachDeviceReqCbFn>
|
||||
{
|
||||
public:
|
||||
DetachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
|
||||
smo::Callback<sal_mlo_detachDeviceReqCbFn> cb)
|
||||
: smo::NonPostedAsynchronousContinuation<sal_mlo_detachDeviceReqCbFn>(
|
||||
std::move(cb)),
|
||||
spec(spec)
|
||||
{}
|
||||
|
||||
public:
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec> spec;
|
||||
|
||||
public:
|
||||
void detachDeviceReq1(
|
||||
std::shared_ptr<DetachDeviceReq> context,
|
||||
bool success)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to destroy Livox device: "
|
||||
<< context->spec->deviceIdentifier << "\n";
|
||||
context->callOriginalCb(false, context->spec);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the device in g_attachedDevices and remove it.
|
||||
auto eraseIt = std::find_if(
|
||||
g_attachedDevices.begin(), g_attachedDevices.end(),
|
||||
[context](const std::shared_ptr<livoxProto1::Device>& dev)
|
||||
{
|
||||
const std::string& devId = dev->discoveredDevice.deviceIdentifier;
|
||||
std::string devIdPrefix = devId.substr(
|
||||
0, std::min<size_t>(14, devId.size()));
|
||||
return devIdPrefix == context->spec->deviceSelector.substr(
|
||||
0, std::min<size_t>(14, context->spec->deviceSelector.size()));
|
||||
}
|
||||
);
|
||||
|
||||
if (eraseIt == g_attachedDevices.end())
|
||||
{
|
||||
std::cerr << __func__ << ": Race condition: device not found "
|
||||
"in g_attachedDevices for detachment: "
|
||||
<< context->spec->deviceIdentifier << "\n";
|
||||
context->callOriginalCb(false, context->spec);
|
||||
return;
|
||||
}
|
||||
|
||||
g_attachedDevices.erase(eraseIt);
|
||||
std::cout << __func__ << ": Successfully detached Livox device: "
|
||||
<< context->spec->deviceIdentifier << "\n";
|
||||
|
||||
context->callOriginalCb(success, context->spec);
|
||||
}
|
||||
};
|
||||
|
||||
// Callback function declarations
|
||||
extern "C" sal_mlo_initializeIndFn livoxGen1_initializeInd;
|
||||
extern "C" sal_mlo_finalizeIndFn livoxGen1_finalizeInd;
|
||||
@@ -152,7 +253,7 @@ extern "C" int livoxGen1_finalizeInd(void)
|
||||
extern "C" void livoxGen1_attachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
|
||||
const std::shared_ptr<smo::ComponentThread>& componentThread,
|
||||
smo::sense_api::sal_mlo_attachDeviceReqCbFn cb
|
||||
Callback<smo::sense_api::sal_mlo_attachDeviceReqCbFn> cb
|
||||
)
|
||||
{
|
||||
if (!livoxProto1.livoxProto1_getOrCreateDeviceReq)
|
||||
@@ -170,7 +271,10 @@ extern "C" void livoxGen1_attachDeviceReq(
|
||||
for (const auto& dev : g_attachedDevices)
|
||||
{
|
||||
if (dev->discoveredDevice.deviceIdentifier == desc->deviceIdentifier)
|
||||
{ return; }
|
||||
{
|
||||
cb.callbackFn(true, desc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse integer parameters from provider params with defaults
|
||||
@@ -245,39 +349,23 @@ extern "C" void livoxGen1_attachDeviceReq(
|
||||
}
|
||||
}
|
||||
|
||||
auto request = std::make_shared<AttachDeviceReq>(desc, cb);
|
||||
|
||||
(*livoxProto1.livoxProto1_getOrCreateDeviceReq)(
|
||||
desc->deviceSelector, // deviceIdentifier (broadcast code)
|
||||
componentThread,
|
||||
handshakeTimeoutMs, retryDelayMs,
|
||||
smoIp, smoSubnetNbits,
|
||||
dataPort, cmdPort, imuPort,
|
||||
[desc, cb](
|
||||
bool success, std::shared_ptr<livoxProto1::Device> dev) -> void
|
||||
{
|
||||
if (!dev)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to create Livox device: "
|
||||
<< desc->deviceSelector << std::endl;
|
||||
cb(false, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
g_attachedDevices.push_back(dev);
|
||||
if (1 || OptionParser::getOptions().verbose)
|
||||
{
|
||||
std::cout << __func__ << ": Successfully attached Livox "
|
||||
"device: " << desc->deviceSelector << " (ID: "
|
||||
<< desc->deviceIdentifier << ")\n";
|
||||
}
|
||||
|
||||
cb(success, desc);
|
||||
}
|
||||
);
|
||||
{request, std::bind(
|
||||
&AttachDeviceReq::attachDeviceReq1,
|
||||
request.get(), request,
|
||||
std::placeholders::_1, std::placeholders::_2)});
|
||||
}
|
||||
|
||||
extern "C" void livoxGen1_detachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
|
||||
smo::sense_api::sal_mlo_detachDeviceReqCbFn cb
|
||||
Callback<smo::sense_api::sal_mlo_detachDeviceReqCbFn> cb
|
||||
)
|
||||
{
|
||||
/** FIXME:
|
||||
@@ -307,51 +395,18 @@ extern "C" void livoxGen1_detachDeviceReq(
|
||||
std::cerr << std::string(__func__)
|
||||
<< ": Device not found for detachment: "
|
||||
<< desc->deviceIdentifier << std::endl;
|
||||
cb(false, desc);
|
||||
cb.callbackFn(false, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
auto request = std::make_shared<DetachDeviceReq>(desc, cb);
|
||||
|
||||
(*livoxProto1.livoxProto1_destroyDeviceReq)(
|
||||
*it,
|
||||
[cb, desc](bool success)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
std::cerr << __func__ << ": Failed to destroy Livox device: "
|
||||
<< desc->deviceIdentifier << "\n";
|
||||
cb(false, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the device in g_attachedDevices and remove it.
|
||||
auto eraseIt = std::find_if(
|
||||
g_attachedDevices.begin(), g_attachedDevices.end(),
|
||||
[desc](const std::shared_ptr<livoxProto1::Device>& dev)
|
||||
{
|
||||
const std::string& devId = dev->discoveredDevice.deviceIdentifier;
|
||||
std::string devIdPrefix = devId.substr(
|
||||
0, std::min<size_t>(14, devId.size()));
|
||||
return devIdPrefix == desc->deviceSelector.substr(
|
||||
0, std::min<size_t>(14, desc->deviceSelector.size()));
|
||||
}
|
||||
);
|
||||
|
||||
if (eraseIt == g_attachedDevices.end())
|
||||
{
|
||||
std::cerr << __func__ << ": Race condition: device not found "
|
||||
"in g_attachedDevices for detachment: "
|
||||
<< desc->deviceIdentifier << "\n";
|
||||
cb(false, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
g_attachedDevices.erase(eraseIt);
|
||||
std::cout << __func__ << ": Successfully detached Livox device: "
|
||||
<< desc->deviceIdentifier << "\n";
|
||||
|
||||
cb(success, desc);
|
||||
}
|
||||
);
|
||||
{request, std::bind(
|
||||
&DetachDeviceReq::detachDeviceReq1,
|
||||
request.get(), request,
|
||||
std::placeholders::_1)});
|
||||
}
|
||||
|
||||
// Exported function
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <xcb/xcb.h>
|
||||
#include <user/senseApiDesc.h>
|
||||
#include <user/deviceAttachmentSpec.h>
|
||||
#include <callback.h>
|
||||
#include <xcbXorg/xcbXorg.h>
|
||||
#include "xcbWindow.h"
|
||||
|
||||
@@ -276,7 +277,7 @@ static int xcbWindow_finalizeInd(void)
|
||||
static void xcbWindow_attachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& desc,
|
||||
const std::shared_ptr<smo::ComponentThread>& componentThread,
|
||||
smo::sense_api::sal_mlo_attachDeviceReqCbFn cb
|
||||
smo::Callback<smo::sense_api::sal_mlo_attachDeviceReqCbFn> cb
|
||||
)
|
||||
{
|
||||
// Not used yet, but may be used later.
|
||||
@@ -289,12 +290,12 @@ static void xcbWindow_attachDeviceReq(
|
||||
<< g_attachedWindows.back()->stringify()
|
||||
<< "\n";
|
||||
|
||||
cb(true, desc);
|
||||
cb.callbackFn(true, desc);
|
||||
}
|
||||
|
||||
static void xcbWindow_detachDeviceReq(
|
||||
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec,
|
||||
smo::sense_api::sal_mlo_detachDeviceReqCbFn cb
|
||||
smo::Callback<smo::sense_api::sal_mlo_detachDeviceReqCbFn> cb
|
||||
)
|
||||
{
|
||||
auto it = std::find_if(g_attachedWindows.begin(), g_attachedWindows.end(),
|
||||
@@ -308,7 +309,7 @@ static void xcbWindow_detachDeviceReq(
|
||||
std::cerr << __func__ << ": Device not found for detachment:\n"
|
||||
<< spec->stringify() << "\n";
|
||||
|
||||
cb(false, spec);
|
||||
cb.callbackFn(false, spec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -316,7 +317,7 @@ static void xcbWindow_detachDeviceReq(
|
||||
std::cout << __func__ << ": Detached X11 window device:\n"
|
||||
<< spec->stringify() << "\n";
|
||||
|
||||
cb(true, spec);
|
||||
cb.callbackFn(true, spec);
|
||||
}
|
||||
|
||||
// SenseApi descriptor
|
||||
|
||||
Reference in New Issue
Block a user