@@ -12,6 +12,7 @@ import (
12
12
"fmt"
13
13
"io"
14
14
"os/exec"
15
+ "sort"
15
16
"sync"
16
17
"time"
17
18
)
@@ -43,14 +44,14 @@ type Manager struct {
43
44
mutex sync.Mutex
44
45
45
46
counter int64
46
- Processes map [int64 ]* Process
47
+ processes map [int64 ]* Process
47
48
}
48
49
49
50
// GetManager returns a Manager and initializes one as singleton if there's none yet
50
51
func GetManager () * Manager {
51
52
if manager == nil {
52
53
manager = & Manager {
53
- Processes : make (map [int64 ]* Process ),
54
+ processes : make (map [int64 ]* Process ),
54
55
}
55
56
}
56
57
return manager
@@ -60,7 +61,7 @@ func GetManager() *Manager {
60
61
func (pm * Manager ) Add (description string , cmd * exec.Cmd , cancel context.CancelFunc ) int64 {
61
62
pm .mutex .Lock ()
62
63
pid := pm .counter + 1
63
- pm .Processes [pid ] = & Process {
64
+ pm .processes [pid ] = & Process {
64
65
PID : pid ,
65
66
Description : description ,
66
67
Start : time .Now (),
@@ -76,20 +77,32 @@ func (pm *Manager) Add(description string, cmd *exec.Cmd, cancel context.CancelF
76
77
// Remove a process from the ProcessManager.
77
78
func (pm * Manager ) Remove (pid int64 ) {
78
79
pm .mutex .Lock ()
79
- delete (pm .Processes , pid )
80
+ delete (pm .processes , pid )
80
81
pm .mutex .Unlock ()
81
82
}
82
83
83
84
// Cancel a process in the ProcessManager.
84
85
func (pm * Manager ) Cancel (pid int64 ) {
85
86
pm .mutex .Lock ()
86
- process , ok := pm .Processes [pid ]
87
+ process , ok := pm .processes [pid ]
87
88
pm .mutex .Unlock ()
88
89
if ok {
89
90
process .Cancel ()
90
91
}
91
92
}
92
93
94
+ // Processes gets the processes in a thread safe manner
95
+ func (pm * Manager ) Processes () []* Process {
96
+ pm .mutex .Lock ()
97
+ processes := make ([]* Process , 0 , len (pm .processes ))
98
+ for _ , process := range pm .processes {
99
+ processes = append (processes , process )
100
+ }
101
+ pm .mutex .Unlock ()
102
+ sort .Sort (processList (processes ))
103
+ return processes
104
+ }
105
+
93
106
// Exec a command and use the default timeout.
94
107
func (pm * Manager ) Exec (desc , cmdName string , args ... string ) (string , string , error ) {
95
108
return pm .ExecDir (- 1 , "" , desc , cmdName , args ... )
@@ -152,24 +165,16 @@ func (pm *Manager) ExecDirEnvStdIn(timeout time.Duration, dir, desc string, env
152
165
return stdOut .String (), stdErr .String (), err
153
166
}
154
167
155
- // Kill and remove a process from list.
156
- func (pm * Manager ) Kill (pid int64 ) error {
157
- if proc , exists := pm .Processes [pid ]; exists {
158
- pm .mutex .Lock ()
159
- if proc .Cancel != nil {
160
- proc .Cancel ()
161
- }
162
- if proc .Cmd != nil &&
163
- proc .Cmd .Process != nil &&
164
- proc .Cmd .ProcessState != nil &&
165
- ! proc .Cmd .ProcessState .Exited () {
166
- if err := proc .Cmd .Process .Kill (); err != nil {
167
- return fmt .Errorf ("failed to kill process(%d/%s): %v" , pid , proc .Description , err )
168
- }
169
- }
170
- delete (pm .Processes , pid )
171
- pm .mutex .Unlock ()
172
- }
168
+ type processList []* Process
169
+
170
+ func (l processList ) Len () int {
171
+ return len (l )
172
+ }
173
+
174
+ func (l processList ) Less (i , j int ) bool {
175
+ return l [i ].PID < l [j ].PID
176
+ }
173
177
174
- return nil
178
+ func (l processList ) Swap (i , j int ) {
179
+ l [i ], l [j ] = l [j ], l [i ]
175
180
}
0 commit comments