Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct process information caching and command line retrieval under Windows #527

Merged
merged 1 commit into from
Jun 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Correct process information caching and command line retrieval under …
…Windows
  • Loading branch information
dustin-johnson committed Jun 21, 2018
commit eda4cac1f3b5376018404b24cc42da4ccffe2d88
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
3.7.0 (in progress)
================
* Your contribution here.
* [#527](https://github.com/oshi/oshi/pull/527): Correct process information caching and command line retrieval under Windows - [@dustin-johnson](https://github.com/dustin-johnson).

3.6.0 (6/20/2018)
================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ public List<OSProcess> getProcesses(Collection<Integer> pids) {
* Private method to do the heavy lifting for all the getProcess functions.
*
* @param pids
* A collection of pids to query. If null, the entire process
* list will be queried.
* A collection of pids to query. If null, the entire process
* list will be queried.
* @return A corresponding list of processes
*/
private List<OSProcess> processMapToList(Collection<Integer> pids) {
Expand Down Expand Up @@ -374,11 +374,14 @@ private List<OSProcess> processMapToList(Collection<Integer> pids) {

// Get the rest of the data we don't already have from the registry
updateRegistryStats(pids, tempProcessMap, now);

// Command Line only accessible via WMI.
// Utilize cache to only update new processes
Set<Integer> emptyCommandLines = new HashSet<>();
for (Integer pid : tempProcessMap.keySet()) {
if (this.processMap.containsKey(pid) && this.processMap.get(pid).getCommandLine().isEmpty()) {
// If the process is not in the cache yet, or it's in the cache but has an empty command line.
OSProcess cachedProcess = this.processMap.get(pid);
if (cachedProcess == null || cachedProcess.getCommandLine().isEmpty()) {
emptyCommandLines.add(pid);
}
}
Expand Down Expand Up @@ -411,7 +414,6 @@ private List<OSProcess> processMapToList(Collection<Integer> pids) {
}

private void updateRegistryStats(Collection<Integer> pids, Map<Integer, OSProcess> tempProcessMap, long now) {

List<Integer> pidsToKeep = new ArrayList<>(tempProcessMap.keySet().size());

// Sequentially increase the buffer until everything fits.
Expand Down Expand Up @@ -470,7 +472,7 @@ private void updateRegistryStats(Collection<Integer> pids, Map<Integer, OSProces

proc.setUpTime(
(perfTime100nSec - pPerfData.getLong(perfCounterBlockOffset + this.elapsedTimeOffset))
/ 10000L);
/ 10_000L);
proc.setStartTime(now - proc.getUpTime());
proc.setBytesRead(pPerfData.getLong(perfCounterBlockOffset + this.ioReadOffset));
proc.setBytesWritten(pPerfData.getLong(perfCounterBlockOffset + this.ioWriteOffset));
Expand All @@ -480,10 +482,11 @@ private void updateRegistryStats(Collection<Integer> pids, Map<Integer, OSProces
pPerfData.getInt(perfCounterBlockOffset + this.creatingProcessIdOffset));
proc.setPriority(pPerfData.getInt(perfCounterBlockOffset + this.priorityBaseOffset));

// If start time is newer than cached version, delete
// cache
if (this.processMap.containsKey(proc.getProcessID())
&& this.processMap.get(proc.getProcessID()).getStartTime() < proc.getStartTime()) {
// If there is a cached version that isn't this version and the start time is newer than cached
// version by an error margin of 200ms, delete the cache
OSProcess cachedProcess = this.processMap.get(proc.getProcessID());
if (cachedProcess != null && cachedProcess != proc &&
Math.abs(cachedProcess.getStartTime() - proc.getStartTime()) > 200) {
this.processMap.remove(proc.getProcessID());
}
}
Expand Down
15 changes: 15 additions & 0 deletions oshi-core/src/test/java/oshi/software/os/OperatingSystemTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
Expand All @@ -37,6 +39,19 @@
*/
public class OperatingSystemTest {

@Test
public void testGetCommandLine() {
int processesWithNonEmptyCmdLine = 0;

for (OSProcess process : new SystemInfo().getOperatingSystem().getProcesses(0, null)) {
if (!process.getCommandLine().trim().isEmpty()) {
processesWithNonEmptyCmdLine++;
}
}

assertTrue(processesWithNonEmptyCmdLine >= 1);
}

/**
* Test operating system
*/
Expand Down