1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.core5.reactor;
28
29 import java.util.concurrent.atomic.AtomicInteger;
30
31 final class IOWorkers {
32
33 interface Selector {
34
35 SingleCoreIOReactor next();
36
37 }
38
39 static Selector newSelector(final SingleCoreIOReactor[] dispatchers) {
40 return isPowerOfTwo(dispatchers.length)
41 ? new PowerOfTwoSelector(dispatchers)
42 : new GenericSelector(dispatchers);
43 }
44
45 private static boolean isPowerOfTwo(final int val) {
46 return (val & -val) == val;
47 }
48
49 private static void validate(final SingleCoreIOReactor dispatcher) {
50 if (dispatcher.getStatus() == IOReactorStatus.SHUT_DOWN) {
51 throw new IOReactorShutdownException("I/O reactor has been shut down");
52 }
53 }
54
55 private static final class PowerOfTwoSelector implements Selector {
56
57 private final AtomicInteger idx = new AtomicInteger(0);
58 private final SingleCoreIOReactor[] dispatchers;
59
60 PowerOfTwoSelector(final SingleCoreIOReactor[] dispatchers) {
61 this.dispatchers = dispatchers;
62 }
63
64 @Override
65 public SingleCoreIOReactor next() {
66 final SingleCoreIOReactor dispatcher = dispatchers[idx.getAndIncrement() & (dispatchers.length - 1)];
67 validate(dispatcher);
68 return dispatcher;
69 }
70 }
71
72 private static final class GenericSelector implements Selector {
73
74 private final AtomicInteger idx = new AtomicInteger(0);
75 private final SingleCoreIOReactor[] dispatchers;
76
77 GenericSelector(final SingleCoreIOReactor[] dispatchers) {
78 this.dispatchers = dispatchers;
79 }
80
81 @Override
82 public SingleCoreIOReactor next() {
83 final SingleCoreIOReactor dispatcher = dispatchers[(idx.getAndIncrement() & Integer.MAX_VALUE) % dispatchers.length];
84 validate(dispatcher);
85 return dispatcher;
86 }
87 }
88
89 }