UNPKG

3.3 kBPlain TextView Raw
1function create-pool (n)
2 T = this
3 n = Math.floor n
4 throw '.createPool( num ): number of threads must be a Number > 0' unless n > 0
5
6 pool = []
7 idle-threads = []
8 q = { first: null, last: null, length: 0 }
9 pool-object = {
10 on: on-event
11 load: pool-load
12 destroy: destroy
13 pending-jobs: get-pending-jobs
14 idle-threads: get-idle-threads
15 total-threads: get-num-threads
16 any: { eval: eval-any, emit: emit-any }
17 all: { eval: eval-all, emit: emit-all }
18 }
19
20 try
21 while n-- => pool[n] = idle-threads[n] = T.create!
22 catch e
23 destroy \rudely
24 throw e
25
26 return pool-object
27
28 ### Helper Functions Start Here ###
29
30 function pool-load (path, cb)
31 i = pool.length
32 while i--
33 pool[i].load path, cb
34 return
35
36 function next-job (t)
37 job = q-pull!
38 if job
39 if job.type is 1 # RUN
40 t.eval job.src-text-or-event-type, (e, d) ->
41 next-job t
42 f = job.cb-or-data
43 if typeof f is \function
44 try
45 f.call t, e, d
46 catch e
47 return e
48 else
49 t.emit job.src-text-or-event-type, f
50 else if job.type is 2 # EMIT
51 t.emit job.src-text-or-event-type, job.cb-or-data
52 next-job t
53 else
54 idle-threads.push t
55 return
56
57 function q-push (src-text-or-event-type, cb-or-data, type)
58 job = { src-text-or-event-type, cb-or-data, type, next: null }
59 if q.last
60 q.last = q.last.next = job
61 else
62 q.first = q.last = job
63 q.length++
64 return
65
66 function q-pull
67 job = q.first
68 if job
69 if q.last is job then q.first = q.last = null else q.first = job.next
70 q.length--
71 return job
72
73 function eval-any (src, cb)
74 q-push src, cb, 1 # RUN
75 next-job idle-threads.pop! if idle-threads.length
76 return pool-object
77
78 function eval-all (src, cb)
79 pool.for-each (v, i, o) -> v.eval src, cb
80 return pool-object
81
82 function emit-any (event, data)
83 q-push event, data, 2 # EMIT
84 next-job idle-threads.pop! if idle-threads.length
85 return pool-object
86
87 function emit-all (event, data)
88 pool.for-each (v, i, o) -> v.emit event, data
89 return pool-object
90
91 function on-event (event, cb)
92 pool.for-each (v, i, o) -> v.on event, cb
93 return this
94
95 function destroy (rudely)
96 err = -> throw 'This thread pool has been destroyed'
97 be-nice = -> if q.length then setTimeout be-nice, 666 else be-rude!
98 be-rude = ->
99 q.length = 0
100 q.first = null
101 pool.for-each (v, i, o) -> v.destroy!
102 pool-object.eval = pool-object.total-threads = pool-object.idle-threads =
103 pool-object.pendingJobs = pool-object.destroy = err
104 if rudely then be-rude! else be-nice!
105 return
106
107 function get-num-threads => pool.length
108 function get-idle-threads => idle-threads.length
109 function get-pending-jobs => q.length