var kPipelineStateChangeListenerNamePrefix = 'MLPipelineStateChangeListener';
//PipelineManager::createPipeline() begin
+var ValidPipelineDisposeExceptions = ['NotFoundError', 'NotSupportedError', 'AbortError'];
+
var nextPipelineId = 1;
function NextPipelineId() {
return nextPipelineId++;
//Pipeline::stop() end
//Pipeline::dispose() begin
+Pipeline.prototype.dispose = function() {
+ var result = native_.callSync('MLPipelineDispose', { id: this._id });
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObjectAndValidate(
+ result,
+ ValidPipelineDisposeExceptions,
+ AbortError
+ );
+ }
+};
//Pipeline::dispose() end
//Pipeline::getNodeInfo() begin
// Pipeline API begin
REGISTER_METHOD(MLPipelineManagerCreatePipeline);
REGISTER_METHOD(MLPipelineGetState);
-
+ REGISTER_METHOD(MLPipelineDispose);
// Pipeline API end
#undef REGISTER_METHOD
// Pipeline::stop() end
// Pipeline::dispose() begin
+void MlInstance::MLPipelineDispose(const picojson::value& args, picojson::object& out) {
+ ScopeLogger("args: %s", args.serialize().c_str());
+
+ if (!args.get(kId).is<double>()) {
+ LoggerD("id is not a number");
+ ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid pipeline"}, &out);
+ return;
+ }
+
+ auto id = static_cast<int>(args.get(kId).get<double>());
+ auto ret = pipeline_manager_.DisposePipeline(id);
+ if (!ret) {
+ ReportError(ret, &out);
+ return;
+ }
+
+ ReportSuccess(out);
+}
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin
// Valve::setOpen() begin
// Valve::setOpen() end
-
// Pipeline API end
} // namespace ml
// Pipeline::stop() end
// Pipeline::dispose() begin
-
+ void MLPipelineDispose(const picojson::value& args, picojson::object& out);
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin
Pipeline::~Pipeline() {
ScopeLogger("Destroying pipeline: [%d]", id_);
+ if (!pipeline_) {
+ LoggerD("pipeline_ has already been destroyed");
+ return;
+ }
+
auto ret = ml_pipeline_destroy(pipeline_);
if (ML_ERROR_NONE != ret) {
LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret));
// Pipeline::stop() end
// Pipeline::dispose() begin
+PlatformResult Pipeline::Dispose() {
+ ScopeLogger("id_: [%d]", id_);
+
+ auto ret = ml_pipeline_destroy(pipeline_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret));
+ return util::ToPlatformResult(ret, "Could not dispose the pipeline");
+ }
+ LoggerD("ml_pipeline_destroy() succeeded");
+ pipeline_ = nullptr;
+
+ return PlatformResult{};
+}
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin
// Pipeline::stop() end
// Pipeline::dispose() begin
-
+ PlatformResult Dispose();
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin
// Pipeline::stop() end
// Pipeline::dispose() begin
+PlatformResult PipelineManager::DisposePipeline(int id) {
+ ScopeLogger("id: [%d]", id);
+
+ auto pipeline_it = pipelines_.find(id);
+ if (pipelines_.end() == pipeline_it) {
+ return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
+ }
+ /*
+ * Native ml_pipeline_destroy() may fail (I've checked its implementation),
+ * so we shouldn't just call pipelines_.erase(id) and let the ~Pipeline()
+ * destroy the pipeline, but only call pipelines_.erase(id) when
+ * pipeline->Dispose() succeeds.
+ */
+ auto ret = pipeline_it->second->Dispose();
+ if (ret) {
+ pipelines_.erase(id);
+ }
+
+ return ret;
+}
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin
// Pipeline::stop() end
// Pipeline::dispose() begin
-
+ PlatformResult DisposePipeline(int id);
// Pipeline::dispose() end
// Pipeline::getNodeInfo() begin