function [returnCode, out] = cppEvaluateRequest(argsIn, taskId)
% Evaluate parfeval request on worker in a Cpp pool

% Copyright 2021 The MathWorks, Inc.

dctSchedulerMessage(6,"In cppEvaluateRequest");
logOnExit = onCleanup(@() dctSchedulerMessage(6, 'Leaving cppEvaluateRequest'));

stackFilesToIgnore = {mfilename};
returnCode = 0;

% Handle 'mpi'-ness state.
pctPreRemoteEvaluation('mpi_mi');

userFcn = argsIn{1};
numArgsOut = argsIn{2};
args = argsIn{3};
dctSchedulerMessage(3, "cppEvaluateRequest for taskId: %d got function: %s", taskId, func2str(userFcn));

try
outArgs = cell(1, numArgsOut);

% Use builtin('feval', ...) to avoid dispatching to an FEVAL method
% of one of inputArgsCell.
if numArgsOut == 0
builtin('feval', userFcn, args{:});
else
[outArgs{1:numArgsOut}] = builtin('feval', userFcn, args{:});
end
catch E
[isMissingSourceError, ~] = parallel.internal.pool.missingSourcesFromException(E);
if isMissingSourceError
returnCode = 2;
else
returnCode = 1;
end

err = ParallelException.hBuildFromRemoteException(E, stackFilesToIgnore);
out = {returnCode, err};
dctSchedulerMessage(2, "Leaving cppEvaluateRequest with error", err);

return;
end

out = {returnCode, outArgs};

end