@@ -11,7 +11,6 @@ import (
1111 "runtime"
1212 "sync"
1313 "sync/atomic"
14- "time"
1514
1615 yarax "github.com/VirusTotal/yara-x/go"
1716 orderedmap "github.com/wk8/go-ordered-map/v2"
@@ -34,6 +33,7 @@ type Config struct {
3433 IgnoreSelf bool
3534 IgnoreTags []string
3635 IncludeDataFiles bool
36+ MaxScanners int
3737 MinFileRisk int
3838 MinRisk int
3939 OCI bool
@@ -175,23 +175,17 @@ func NewScannerPool(rules *yarax.Rules, maxScanners int) (*ScannerPool, error) {
175175 available : make (chan * yarax.Scanner , maxScanners ),
176176 maxScanners : int32 (maxScanners ),
177177 scanners : make ([]* yarax.Scanner , 0 , maxScanners ),
178+ closed : atomic.Bool {},
178179 }
179180
180- pool .closed .Store (false )
181-
182- // Create a subset of the maximum number of scanners to avoid contention
183- initialScanners := maxScanners / 2 + 1
184- for i := 0 ; i < initialScanners ; i ++ {
185- scanner , err := pool .createScanner ()
186- if err != nil {
187- pool .Cleanup ()
188- return nil , fmt .Errorf ("failed to create initial scanner: %w" , err )
189- }
190- pool .scanners = append (pool .scanners , scanner )
191- pool .available <- scanner
192- atomic .AddInt32 (& pool .currentCount , 1 )
181+ scanner := yarax .NewScanner (rules )
182+ if scanner == nil {
183+ return nil , fmt .Errorf ("failed to create scanner" )
193184 }
194185
186+ pool .available <- scanner
187+ atomic .AddInt32 (& pool .currentCount , 1 )
188+
195189 return pool , nil
196190}
197191
@@ -236,39 +230,27 @@ func (p *ScannerPool) Get() (*yarax.Scanner, error) {
236230 return nil , fmt .Errorf ("scanner pool is closed" )
237231 }
238232
233+ // Retrieve an existing scanner
234+ // If none are available, create up to the maximum number of scanners
239235 select {
240236 case scanner := <- p .available :
241- if scanner == nil {
242- return nil , fmt .Errorf ("received nil scanner from pool" )
243- }
244237 return scanner , nil
245- case <- time .After (100 * time .Millisecond ):
246- }
247-
248- // Create a new scanner if we aren't already running the maximum number
249- p .mu .Lock ()
250- current := atomic .LoadInt32 (& p .currentCount )
251- if current < p .maxScanners {
252- scanner , err := p .createScanner ()
253- if err != nil {
238+ default :
239+ p .mu .Lock ()
240+ if atomic .LoadInt32 (& p .currentCount ) < p .maxScanners {
241+ scanner , err := p .createScanner ()
242+ if err != nil {
243+ p .mu .Unlock ()
244+ return nil , fmt .Errorf ("create scanner: %w" , err )
245+ }
246+ p .scanners = append (p .scanners , scanner )
247+ atomic .AddInt32 (& p .currentCount , 1 )
254248 p .mu .Unlock ()
255- return nil , fmt . Errorf ( "create scanner: %w" , err )
249+ return scanner , nil
256250 }
257- p .scanners = append (p .scanners , scanner )
258- atomic .AddInt32 (& p .currentCount , 1 )
259251 p .mu .Unlock ()
260- return scanner , nil
261- }
262- p .mu .Unlock ()
263252
264- select {
265- case scanner := <- p .available :
266- if scanner == nil {
267- return nil , fmt .Errorf ("received nil scanner from pool" )
268- }
269- return scanner , nil
270- case <- time .After (10 * time .Second ):
271- return nil , fmt .Errorf ("timeout waiting for available scanner" )
253+ return <- p .available , nil
272254 }
273255}
274256
@@ -277,20 +259,7 @@ func (p *ScannerPool) Put(scanner *yarax.Scanner) {
277259 if scanner == nil || p .closed .Load () {
278260 return
279261 }
280-
281- select {
282- case p .available <- scanner :
283- default :
284- p .mu .Lock ()
285- defer func () {
286- p .mu .Unlock ()
287- if atomic .LoadInt32 (& p .currentCount ) > p .maxScanners / 2 {
288- runtime .GC ()
289- }
290- }()
291- scanner .Destroy ()
292- atomic .AddInt32 (& p .currentCount , - 1 )
293- }
262+ p .available <- scanner
294263}
295264
296265// Cleanup destroys all scanners in the pool.
0 commit comments