State providers keep track of the latest event that was handled is returns
this time as the current end time.
State system analysis module use this time to determine if an analysis is ready
to be queried. Also on the way to fix bug 488757.
Change-Id: I58308da05c3105f0a528398622658c3fb3f2250f
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/69760
Reviewed-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
private final Thread fEventHandlerThread;
private boolean fStateSystemAssigned;
private final Thread fEventHandlerThread;
private boolean fStateSystemAssigned;
/** State system in which to insert the state changes */
private @Nullable ITmfStateSystemBuilder fSS = null;
/** State system in which to insert the state changes */
private @Nullable ITmfStateSystemBuilder fSS = null;
+ /* The last safe time at which this state provider can be queried */
+ private volatile long fSafeTime;
+
/**
* Instantiate a new state provider plugin.
*
/**
* Instantiate a new state provider plugin.
*
fTrace = trace;
fEventsQueue = new BufferedBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE, DEFAULT_EVENTS_CHUNK_SIZE);
fStateSystemAssigned = false;
fTrace = trace;
fEventsQueue = new BufferedBlockingQueue<>(DEFAULT_EVENTS_QUEUE_SIZE, DEFAULT_EVENTS_CHUNK_SIZE);
fStateSystemAssigned = false;
+ // set the safe time to before the trace start, the analysis has not yet started
+ fSafeTime = trace.getStartTime().toNanos() - 1;
fEventHandlerThread = new Thread(new EventProcessor(), id + " Event Handler"); //$NON-NLS-1$
}
fEventHandlerThread = new Thread(new EventProcessor(), id + " Event Handler"); //$NON-NLS-1$
}
return fTrace.getStartTime().toNanos();
}
return fTrace.getStartTime().toNanos();
}
+ /**
+ * @since 2.0
+ */
+ @Override
+ public long getLatestSafeTime() {
+ return fSafeTime;
+ }
+
@Override
public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) {
fSS = ssb;
@Override
public void assignTargetStateSystem(ITmfStateSystemBuilder ssb) {
fSS = ssb;
continue;
}
currentEvent = event;
continue;
}
currentEvent = event;
+ fSafeTime = event.getTimestamp().toNanos() - 1;
eventHandle(event);
event = fEventsQueue.take();
}
eventHandle(event);
event = fEventsQueue.take();
}
+ /**
+ * Return the last time at which it is safe to query the state system under
+ * construction, ie not the current end time of the underlying state system,
+ * but the time just before the latest event that has been processed.
+ *
+ * @return The last timestamp at which it is safe to query the state system
+ * underneath
+ * @since 2.0
+ */
+ long getLatestSafeTime();
+
/**
* Assign the target state system where this SCI will insert its state
* changes. Because of dependencies issues, this can normally not be done at
/**
* Assign the target state system where this SCI will insert its state
* changes. Because of dependencies issues, this can normally not be done at
private final CountDownLatch fInitialized = new CountDownLatch(1);
private final Object fRequestSyncObj = new Object();
private final CountDownLatch fInitialized = new CountDownLatch(1);
private final Object fRequestSyncObj = new Object();
- @Nullable private ITmfStateSystemBuilder fStateSystem;
- @Nullable private ITmfStateProvider fStateProvider;
- @Nullable private IStateHistoryBackend fHtBackend;
- @Nullable private ITmfEventRequest fRequest;
- @Nullable private TmfTimeRange fTimeRange = null;
+ private @Nullable ITmfStateSystemBuilder fStateSystem;
+ private @Nullable IStateHistoryBackend fHtBackend;
+ private @Nullable ITmfEventRequest fRequest;
+ private @Nullable TmfTimeRange fTimeRange = null;
private int fNbRead = 0;
private boolean fInitializationSucceeded;
private int fNbRead = 0;
private boolean fInitializationSucceeded;
+ private volatile @Nullable ITmfStateProvider fStateProvider;
+
/**
* State system backend types
*
/**
* State system backend types
*
return fInitializationSucceeded;
}
return fInitializationSucceeded;
}
+ /**
+ * @since 2.0
+ */
+ @Override
+ public boolean isQueryable(long ts) {
+ /* Return true if there is no state provider available (the analysis is not being built) */
+ ITmfStateProvider provider = fStateProvider;
+ if (provider == null) {
+ return true;
+ }
+ return ts <= provider.getLatestSafeTime();
+ }
+
// ------------------------------------------------------------------------
// TmfAbstractAnalysisModule
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// TmfAbstractAnalysisModule
// ------------------------------------------------------------------------
/* Get the state system according to backend */
StateSystemBackendType backend = getBackendType();
/* Get the state system according to backend */
StateSystemBackendType backend = getBackendType();
ITmfTrace trace = getTrace();
if (trace == null) {
// Analysis was cancelled in the meantime
ITmfTrace trace = getTrace();
if (trace == null) {
// Analysis was cancelled in the meantime
if (provider != null) {
provider.dispose();
}
if (provider != null) {
provider.dispose();
}
if (deleteFiles && (fHtBackend != null)) {
fHtBackend.removeFiles();
}
if (deleteFiles && (fHtBackend != null)) {
fHtBackend.removeFiles();
}
@Override
public void handleCancel() {
super.handleCancel();
@Override
public void handleCancel() {
super.handleCancel();
- if (isCompleteTrace(trace)) {
- disposeProvider(true);
- }