log.tracef("startWork(%s, %s, %s, %s)", work, startTimeout, execContext, workListener);
if (shutdown.get())
throw new WorkRejectedException(bundle.workmanagerShutdown());
WorkException exception = null;
WorkWrapper wrapper = null;
try
{
if (work == null)
throw new WorkRejectedException(bundle.workIsNull());
if (startTimeout < 0)
throw new WorkRejectedException(bundle.startTimeoutIsNegative(startTimeout));
long started = System.currentTimeMillis();
checkAndVerifyWork(work, execContext);
if (workListener != null)
{
WorkEvent event = new WorkEvent(this, WorkEvent.WORK_ACCEPTED, work, null);
workListener.workAccepted(event);
}
if (execContext == null)
{
execContext = new ExecutionContext();
}
final CountDownLatch startedLatch = new CountDownLatch(1);
wrapper = new WorkWrapper(this, work, execContext, workListener, startedLatch, null,
System.currentTimeMillis());
setup(wrapper, workListener);
BlockingExecutor executor = getExecutor(work);
if (startTimeout == WorkManager.INDEFINITE)
{
executor.executeBlocking(wrapper);
}
else
{
executor.executeBlocking(wrapper, startTimeout, TimeUnit.MILLISECONDS);
}
startedLatch.await();
return System.currentTimeMillis() - started;
}
catch (ExecutionTimedOutException etoe)
{
exception = new WorkRejectedException(etoe);
exception.setErrorCode(WorkRejectedException.START_TIMED_OUT);
}
catch (RejectedExecutionException ree)
{
exception = new WorkRejectedException(ree);
}